diff -r 99ef4501205b Objects/stringlib/unicode_format.h --- a/Objects/stringlib/unicode_format.h Thu May 10 16:11:12 2012 +0100 +++ b/Objects/stringlib/unicode_format.h Sun May 13 04:18:09 2012 +0200 @@ -902,11 +902,14 @@ do_markup(SubString *input, PyObject *ar writer->pos += sublen; } - if (field_present) + if (field_present) { + if (iter.str.start == iter.str.end) + writer->overallocate = 0; if (!output_markup(&field_name, &format_spec, format_spec_needs_expanding, conversion, writer, args, kwargs, recursion_depth, auto_number)) return 0; + } } return result; } @@ -921,7 +924,6 @@ build_string(SubString *input, PyObject int recursion_depth, AutoNumber *auto_number) { _PyUnicodeWriter writer; - Py_ssize_t initlen; /* check the recursion level */ if (recursion_depth <= 0) { @@ -930,8 +932,7 @@ build_string(SubString *input, PyObject return NULL; } - initlen = PyUnicode_GET_LENGTH(input->str) + 100; - if (_PyUnicodeWriter_Init(&writer, initlen, 127) == -1) + if (_PyUnicodeWriter_Init(&writer, 0, 0) == -1) return NULL; if (!do_markup(input, args, kwargs, &writer, recursion_depth, diff -r 99ef4501205b Objects/unicodeobject.c --- a/Objects/unicodeobject.c Thu May 10 16:11:12 2012 +0100 +++ b/Objects/unicodeobject.c Sun May 13 04:18:09 2012 +0200 @@ -12893,6 +12893,7 @@ unicode_endswith(PyObject *self, } typedef struct { + int overallocate; PyObject *buffer; void *data; enum PyUnicode_Kind kind; @@ -12910,13 +12911,23 @@ _PyUnicodeWriter_Update(_PyUnicodeWriter Py_LOCAL(int) _PyUnicodeWriter_Init(_PyUnicodeWriter *writer, - Py_ssize_t length, Py_UCS4 maxchar) -{ + Py_ssize_t length, Py_UCS4 maxchar) +{ + writer->overallocate = 1; writer->pos = 0; - writer->buffer = PyUnicode_New(length, maxchar); - if (writer->buffer == NULL) - return -1; - _PyUnicodeWriter_Update(writer); + if (length != 0) { + writer->buffer = PyUnicode_New(length, maxchar); + if (writer->buffer == NULL) + return -1; + _PyUnicodeWriter_Update(writer); + } + else { + writer->buffer = NULL; + writer->maxchar = 0; + writer->data = NULL; + /* invalid kind */ + writer->kind = 5; + } return 0; } @@ -12933,10 +12944,29 @@ _PyUnicodeWriter_Prepare(_PyUnicodeWrite } newlen = writer->pos + length; + if (writer->buffer == NULL) { + if (writer->overallocate) { + /* overallocate by 100% to limit the number of resize */ + if (newlen <= PY_SSIZE_T_MAX / 2) + newlen *= 2; + if (newlen < 100) + newlen = 100; + } + writer->buffer = PyUnicode_New(newlen, maxchar); + if (writer->buffer == NULL) + return -1; + _PyUnicodeWriter_Update(writer); + return 0; + } + if (newlen > PyUnicode_GET_LENGTH(writer->buffer)) { - /* overallocate 25% to limit the number of resize */ - if (newlen <= (PY_SSIZE_T_MAX - newlen / 4)) - newlen += newlen / 4; + if (writer->overallocate) { + /* overallocate by 100% to limit the number of resize */ + if (newlen <= PY_SSIZE_T_MAX / 2) + newlen *= 2; + if (newlen < 100) + newlen = 100; + } if (maxchar > writer->maxchar) { /* resize + widen */ @@ -12966,9 +12996,19 @@ _PyUnicodeWriter_Prepare(_PyUnicodeWrite Py_LOCAL(PyObject *) _PyUnicodeWriter_Finish(_PyUnicodeWriter *writer) { - if (PyUnicode_Resize(&writer->buffer, writer->pos) < 0) { - Py_DECREF(writer->buffer); - return NULL; + if (writer->pos == 0) { + Py_XDECREF(writer->buffer); + Py_INCREF(unicode_empty); + return unicode_empty; + } + if (PyUnicode_GET_LENGTH(writer->buffer) != writer->pos) { + PyObject *newbuffer; + newbuffer = resize_compact(writer->buffer, writer->pos); + if (newbuffer == NULL) { + Py_DECREF(writer->buffer); + return NULL; + } + writer->buffer = newbuffer; } assert(_PyUnicode_CheckConsistency(writer->buffer, 1)); return writer->buffer; @@ -13459,7 +13499,7 @@ PyUnicode_Format(PyObject *format, PyObj fmtcnt = PyUnicode_GET_LENGTH(uformat); fmtpos = 0; - if (_PyUnicodeWriter_Init(&writer, fmtcnt + 100, 127) < 0) + if (_PyUnicodeWriter_Init(&writer, 0, 0) < 0) goto onError; if (PyTuple_Check(args)) { @@ -13810,6 +13850,9 @@ PyUnicode_Format(PyObject *format, PyObj if (sign && len == width) buflen++; + if (fmtcnt < 1) + writer.overallocate = 0; + if (_PyUnicodeWriter_Prepare(&writer, buflen, bufmaxchar) == -1) goto onError;