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:
parent
fc8dca27d3
commit
1d138f1c1a
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue