summaryrefslogtreecommitdiffstats
path: root/Objects/stringlib
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2012-05-07 10:47:02 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2012-05-07 10:47:02 (GMT)
commit202fdca133ce8f5b0c37cca1353070e0721c688d (patch)
tree7e6f1c58ca7b836f8fb8132dea7f85b08d403894 /Objects/stringlib
parent9fad1604110cd7a0bb32792aa6d6c6a63018d51e (diff)
downloadcpython-202fdca133ce8f5b0c37cca1353070e0721c688d.zip
cpython-202fdca133ce8f5b0c37cca1353070e0721c688d.tar.gz
cpython-202fdca133ce8f5b0c37cca1353070e0721c688d.tar.bz2
Close #14716: str.format() now uses the new "unicode writer" API instead of the
PyAccu API. For example, it makes str.format() from 25% to 30% faster on Linux.
Diffstat (limited to 'Objects/stringlib')
-rw-r--r--Objects/stringlib/unicode_format.h60
1 files changed, 19 insertions, 41 deletions
diff --git a/Objects/stringlib/unicode_format.h b/Objects/stringlib/unicode_format.h
index 6807088..85a29f5 100644
--- a/Objects/stringlib/unicode_format.h
+++ b/Objects/stringlib/unicode_format.h
@@ -2,8 +2,6 @@
unicode_format.h -- implementation of str.format().
*/
-#include "accu.h"
-
/* Defines for more efficiently reallocating the string buffer */
#define INITIAL_SIZE_INCREMENT 100
#define SIZE_MULTIPLIER 2
@@ -112,33 +110,6 @@ autonumber_state_error(AutoNumberState state, int field_name_is_empty)
/************************************************************************/
-/*********** Output string management functions ****************/
-/************************************************************************/
-
-/*
- output_data dumps characters into our output string
- buffer.
-
- In some cases, it has to reallocate the string.
-
- It returns a status: 0 for a failed reallocation,
- 1 for success.
-*/
-static int
-output_data(_PyAccu *acc, PyObject *s, Py_ssize_t start, Py_ssize_t end)
-{
- PyObject *substring;
- int r;
-
- substring = PyUnicode_Substring(s, start, end);
- if (substring == NULL)
- return 0;
- r = _PyAccu_Accumulate(acc, substring);
- Py_DECREF(substring);
- return r == 0;
-}
-
-/************************************************************************/
/*********** Format string parsing -- integers and identifiers *********/
/************************************************************************/
@@ -523,7 +494,7 @@ error:
appends to the output.
*/
static int
-render_field(PyObject *fieldobj, SubString *format_spec, _PyAccu *acc)
+render_field(PyObject *fieldobj, SubString *format_spec, unicode_writer_t *writer)
{
int ok = 0;
PyObject *result = NULL;
@@ -566,7 +537,8 @@ render_field(PyObject *fieldobj, SubString *format_spec, _PyAccu *acc)
goto done;
assert(PyUnicode_Check(result));
- ok = output_data(acc, result, 0, PyUnicode_GET_LENGTH(result));
+
+ ok = (unicode_writer_write_str(writer, result, 0, PyUnicode_GET_LENGTH(result)) == 0);
done:
Py_XDECREF(format_spec_object);
Py_XDECREF(result);
@@ -831,7 +803,7 @@ do_conversion(PyObject *obj, Py_UCS4 conversion)
static int
output_markup(SubString *field_name, SubString *format_spec,
int format_spec_needs_expanding, Py_UCS4 conversion,
- _PyAccu *acc, PyObject *args, PyObject *kwargs,
+ unicode_writer_t *writer, PyObject *args, PyObject *kwargs,
int recursion_depth, AutoNumber *auto_number)
{
PyObject *tmp = NULL;
@@ -872,7 +844,7 @@ output_markup(SubString *field_name, SubString *format_spec,
else
actual_format_spec = format_spec;
- if (render_field(fieldobj, actual_format_spec, acc) == 0)
+ if (render_field(fieldobj, actual_format_spec, writer) == 0)
goto done;
result = 1;
@@ -892,7 +864,7 @@ done:
*/
static int
do_markup(SubString *input, PyObject *args, PyObject *kwargs,
- _PyAccu *acc, int recursion_depth, AutoNumber *auto_number)
+ unicode_writer_t *writer, int recursion_depth, AutoNumber *auto_number)
{
MarkupIterator iter;
int format_spec_needs_expanding;
@@ -902,17 +874,21 @@ do_markup(SubString *input, PyObject *args, PyObject *kwargs,
SubString field_name;
SubString format_spec;
Py_UCS4 conversion;
+ int err;
MarkupIterator_init(&iter, input->str, input->start, input->end);
while ((result = MarkupIterator_next(&iter, &literal, &field_present,
&field_name, &format_spec,
&conversion,
&format_spec_needs_expanding)) == 2) {
- if (!output_data(acc, literal.str, literal.start, literal.end))
+ err = unicode_writer_write_str(writer,
+ literal.str, literal.start,
+ literal.end - literal.start);
+ if (err == -1)
return 0;
if (field_present)
if (!output_markup(&field_name, &format_spec,
- format_spec_needs_expanding, conversion, acc,
+ format_spec_needs_expanding, conversion, writer,
args, kwargs, recursion_depth, auto_number))
return 0;
}
@@ -928,7 +904,8 @@ static PyObject *
build_string(SubString *input, PyObject *args, PyObject *kwargs,
int recursion_depth, AutoNumber *auto_number)
{
- _PyAccu acc;
+ unicode_writer_t writer;
+ Py_ssize_t initlen;
/* check the recursion level */
if (recursion_depth <= 0) {
@@ -937,16 +914,17 @@ build_string(SubString *input, PyObject *args, PyObject *kwargs,
return NULL;
}
- if (_PyAccu_Init(&acc))
+ initlen = PyUnicode_GET_LENGTH(input->str) + 100;
+ if (unicode_writer_init(&writer, initlen, 127) == -1)
return NULL;
- if (!do_markup(input, args, kwargs, &acc, recursion_depth,
+ if (!do_markup(input, args, kwargs, &writer, recursion_depth,
auto_number)) {
- _PyAccu_Destroy(&acc);
+ unicode_writer_dealloc(&writer);
return NULL;
}
- return _PyAccu_Finish(&acc);
+ return unicode_writer_finish(&writer);
}
/************************************************************************/