diff options
author | Eric Smith <eric@trueblade.com> | 2008-05-31 01:40:08 (GMT) |
---|---|---|
committer | Eric Smith <eric@trueblade.com> | 2008-05-31 01:40:08 (GMT) |
commit | 1d138f1c1a37a630099b629cf42c0bbe46d1344b (patch) | |
tree | 87b3d6cd5844fb390ecfce7851589687bf757ea8 /Objects/stringlib | |
parent | fc8dca27d330f0c7c47713d2557f190c517c170e (diff) | |
download | cpython-1d138f1c1a37a630099b629cf42c0bbe46d1344b.zip cpython-1d138f1c1a37a630099b629cf42c0bbe46d1344b.tar.gz cpython-1d138f1c1a37a630099b629cf42c0bbe46d1344b.tar.bz2 |
Optimization of str.format() for cases with unicode, long, and float
arguments. This gives about 30% speed improvement for the simplest
(but most common) cases. This patch skips the __format__ dispatch, and
also avoids creating an object to hold the format_spec.
Unfortunately, backporting this to 2.6 is going to be more challenging
due to str/unicode issues with format_spec. I'll work on that next.
Then I'll spend some time profiling and see what that tells me.
Diffstat (limited to 'Objects/stringlib')
-rw-r--r-- | Objects/stringlib/string_format.h | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/Objects/stringlib/string_format.h b/Objects/stringlib/string_format.h index 2e9c7ef..7e62af5 100644 --- a/Objects/stringlib/string_format.h +++ b/Objects/stringlib/string_format.h @@ -483,13 +483,34 @@ render_field(PyObject *fieldobj, SubString *format_spec, OutputString *output) { int ok = 0; PyObject *result = NULL; + PyObject *format_spec_object = NULL; + + STRINGLIB_CHAR* format_spec_start = format_spec->ptr ? + format_spec->ptr : NULL; + Py_ssize_t format_spec_len = format_spec->ptr ? + format_spec->end - format_spec->ptr : 0; + + /* If we know the type exactly, skip the lookup of __format__ and just + call the formatter directly. */ + if (PyUnicode_CheckExact(fieldobj)) + result = _PyUnicode_FormatAdvanced(fieldobj, format_spec_start, + format_spec_len); + else if (PyLong_CheckExact(fieldobj)) + result = _PyLong_FormatAdvanced(fieldobj, format_spec_start, + format_spec_len); + else if (PyFloat_CheckExact(fieldobj)) + result = _PyFloat_FormatAdvanced(fieldobj, format_spec_start, + format_spec_len); + else { + /* We need to create an object out of the pointers we have, because + __format__ takes a string/unicode object for format_spec. */ + format_spec_object = STRINGLIB_NEW(format_spec_start, + format_spec_len); + if (format_spec_object == NULL) + goto done; - /* we need to create an object out of the pointers we have */ - PyObject *format_spec_object = SubString_new_object_or_empty(format_spec); - if (format_spec_object == NULL) - goto done; - - result = PyObject_Format(fieldobj, format_spec_object); + result = PyObject_Format(fieldobj, format_spec_object); + } if (result == NULL) goto done; @@ -512,7 +533,7 @@ render_field(PyObject *fieldobj, SubString *format_spec, OutputString *output) ok = output_data(output, STRINGLIB_STR(result), STRINGLIB_LEN(result)); done: - Py_DECREF(format_spec_object); + Py_XDECREF(format_spec_object); Py_XDECREF(result); return ok; } |