summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@haypocalc.com>2011-12-18 01:43:08 (GMT)
committerVictor Stinner <victor.stinner@haypocalc.com>2011-12-18 01:43:08 (GMT)
commitf644110816a9315a4f8fa4bcbd9fb5c2708ee1ff (patch)
tree5b65ab533043849d0fb940a16212f96e467acb4b /Objects
parentb511aca596d300af45928e9b9dcbcaaa87bc62df (diff)
downloadcpython-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')
-rw-r--r--Objects/unicodeobject.c30
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 */