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.
This commit is contained in:
Eric Smith 2008-05-31 01:40:08 +00:00
parent fc8dca27d3
commit 1d138f1c1a
1 changed files with 27 additions and 6 deletions

View File

@ -483,13 +483,34 @@ render_field(PyObject *fieldobj, SubString *format_spec, OutputString *output)
{ {
int ok = 0; int ok = 0;
PyObject *result = NULL; PyObject *result = NULL;
PyObject *format_spec_object = NULL;
/* we need to create an object out of the pointers we have */ STRINGLIB_CHAR* format_spec_start = format_spec->ptr ?
PyObject *format_spec_object = SubString_new_object_or_empty(format_spec); format_spec->ptr : NULL;
if (format_spec_object == NULL) Py_ssize_t format_spec_len = format_spec->ptr ?
goto done; format_spec->end - format_spec->ptr : 0;
result = PyObject_Format(fieldobj, format_spec_object); /* 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;
result = PyObject_Format(fieldobj, format_spec_object);
}
if (result == NULL) if (result == NULL)
goto done; goto done;
@ -512,7 +533,7 @@ render_field(PyObject *fieldobj, SubString *format_spec, OutputString *output)
ok = output_data(output, ok = output_data(output,
STRINGLIB_STR(result), STRINGLIB_LEN(result)); STRINGLIB_STR(result), STRINGLIB_LEN(result));
done: done:
Py_DECREF(format_spec_object); Py_XDECREF(format_spec_object);
Py_XDECREF(result); Py_XDECREF(result);
return ok; return ok;
} }