[Python-3000-checkins] r63826 - python/branches/py3k/Objects/stringlib/string_format.h
eric.smith
python-3000-checkins at python.org
Sat May 31 03:40:09 CEST 2008
Author: eric.smith
Date: Sat May 31 03:40:08 2008
New Revision: 63826
Log:
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.
Modified:
python/branches/py3k/Objects/stringlib/string_format.h
Modified: python/branches/py3k/Objects/stringlib/string_format.h
==============================================================================
--- python/branches/py3k/Objects/stringlib/string_format.h (original)
+++ python/branches/py3k/Objects/stringlib/string_format.h Sat May 31 03:40:08 2008
@@ -483,13 +483,34 @@
{
int ok = 0;
PyObject *result = NULL;
+ PyObject *format_spec_object = NULL;
- /* 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;
+ 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;
- result = PyObject_Format(fieldobj, format_spec_object);
+ result = PyObject_Format(fieldobj, format_spec_object);
+ }
if (result == NULL)
goto done;
@@ -512,7 +533,7 @@
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;
}
More information about the Python-3000-checkins
mailing list