diff options
author | Victor Stinner <victor.stinner@haypocalc.com> | 2011-12-18 01:43:08 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@haypocalc.com> | 2011-12-18 01:43:08 (GMT) |
commit | f644110816a9315a4f8fa4bcbd9fb5c2708ee1ff (patch) | |
tree | 5b65ab533043849d0fb940a16212f96e467acb4b /Objects/unicodeobject.c | |
parent | b511aca596d300af45928e9b9dcbcaaa87bc62df (diff) | |
download | cpython-f644110816a9315a4f8fa4bcbd9fb5c2708ee1ff.zip cpython-f644110816a9315a4f8fa4bcbd9fb5c2708ee1ff.tar.gz cpython-f644110816a9315a4f8fa4bcbd9fb5c2708ee1ff.tar.bz2 |
Issue #13621: Optimize str.replace(char1, char2)
Use findchar() which is more optimized than a dummy loop using
PyUnicode_READ(). PyUnicode_READ() is a complex and slow macro.
Diffstat (limited to 'Objects/unicodeobject.c')
-rw-r--r-- | Objects/unicodeobject.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index f5f1c46..ab0d9fa 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -10285,7 +10285,6 @@ replace(PyObject *self, PyObject *str1, maxchar = Py_MAX(maxchar, maxchar_str2); if (len1 == len2) { - Py_ssize_t i; /* same length */ if (len1 == 0) goto nothing; @@ -10293,9 +10292,12 @@ replace(PyObject *self, PyObject *str1, /* replace characters */ Py_UCS4 u1, u2; int rkind; + Py_ssize_t index, pos; + char *src; + u1 = PyUnicode_READ_CHAR(str1, 0); - if (findchar(sbuf, PyUnicode_KIND(self), - slen, u1, 1) < 0) + pos = findchar(sbuf, PyUnicode_KIND(self), slen, u1, 1); + if (pos < 0) goto nothing; u2 = PyUnicode_READ_CHAR(str2, 0); u = PyUnicode_New(slen, maxchar); @@ -10303,16 +10305,26 @@ replace(PyObject *self, PyObject *str1, goto error; copy_characters(u, 0, self, 0, slen); rkind = PyUnicode_KIND(u); - for (i = 0; i < PyUnicode_GET_LENGTH(u); i++) - if (PyUnicode_READ(rkind, PyUnicode_DATA(u), i) == u1) { - if (--maxcount < 0) - break; - PyUnicode_WRITE(rkind, PyUnicode_DATA(u), i, u2); - } + + PyUnicode_WRITE(rkind, PyUnicode_DATA(u), pos, u2); + index = 0; + src = sbuf; + while (--maxcount) + { + pos++; + src += pos * PyUnicode_KIND(self); + slen -= pos; + index += pos; + pos = findchar(src, PyUnicode_KIND(self), slen, u1, 1); + if (pos < 0) + break; + PyUnicode_WRITE(rkind, PyUnicode_DATA(u), index + pos, u2); + } } else { int rkind = skind; char *res; + Py_ssize_t i; if (kind1 < rkind) { /* widen substring */ |