Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1d138f1

Browse files
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.
1 parent fc8dca2 commit 1d138f1

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)