Skip to content

Commit 60d66f5

Browse files
author
eric.smith
committed
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. git-svn-id: http://svn.python.org/projects/python/branches/py3k@63826 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent ccc053e commit 60d66f5

1 file changed

Lines changed: 28 additions & 7 deletions

File tree

Objects/stringlib/string_format.h

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -483,13 +483,34 @@ render_field(PyObject *fieldobj, SubString *format_spec, OutputString *output)
483483
{
484484
int ok = 0;
485485
PyObject *result = NULL;
486+
PyObject *format_spec_object = NULL;
487+
488+
STRINGLIB_CHAR* format_spec_start = format_spec->ptr ?
489+
format_spec->ptr : NULL;
490+
Py_ssize_t format_spec_len = format_spec->ptr ?
491+
format_spec->end - format_spec->ptr : 0;
492+
493+
/* If we know the type exactly, skip the lookup of __format__ and just
494+
call the formatter directly. */
495+
if (PyUnicode_CheckExact(fieldobj))
496+
result = _PyUnicode_FormatAdvanced(fieldobj, format_spec_start,
497+
format_spec_len);
498+
else if (PyLong_CheckExact(fieldobj))
499+
result = _PyLong_FormatAdvanced(fieldobj, format_spec_start,
500+
format_spec_len);
501+
else if (PyFloat_CheckExact(fieldobj))
502+
result = _PyFloat_FormatAdvanced(fieldobj, format_spec_start,
503+
format_spec_len);
504+
else {
505+
/* We need to create an object out of the pointers we have, because
506+
__format__ takes a string/unicode object for format_spec. */
507+
format_spec_object = STRINGLIB_NEW(format_spec_start,
508+
format_spec_len);
509+
if (format_spec_object == NULL)
510+
goto done;
486511

487-
/* we need to create an object out of the pointers we have */
488-
PyObject *format_spec_object = SubString_new_object_or_empty(format_spec);
489-
if (format_spec_object == NULL)
490-
goto done;
491-
492-
result = PyObject_Format(fieldobj, format_spec_object);
512+
result = PyObject_Format(fieldobj, format_spec_object);
513+
}
493514
if (result == NULL)
494515
goto done;
495516

@@ -512,7 +533,7 @@ render_field(PyObject *fieldobj, SubString *format_spec, OutputString *output)
512533
ok = output_data(output,
513534
STRINGLIB_STR(result), STRINGLIB_LEN(result));
514535
done:
515-
Py_DECREF(format_spec_object);
536+
Py_XDECREF(format_spec_object);
516537
Py_XDECREF(result);
517538
return ok;
518539
}

0 commit comments

Comments
 (0)