[pypy-commit] pypy default: Fix a complexity bug: if 'b' is a large bytearray,
arigo
noreply at buildbot.pypy.org
Sat Jan 21 10:42:02 CET 2012
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r51561:a9118db9d0bc
Date: 2012-01-21 10:41 +0100
http://bitbucket.org/pypy/pypy/changeset/a9118db9d0bc/
Log: Fix a complexity bug: if 'b' is a large bytearray,
b[small_slice] = small_string
used to take a time proportional to how long the large bytearray is.
diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py
--- a/pypy/objspace/std/bytearrayobject.py
+++ b/pypy/objspace/std/bytearrayobject.py
@@ -624,8 +624,8 @@
if step == 1:
assert start >= 0
- assert slicelength >= 0
- del items[start:start+slicelength]
+ if slicelength > 0:
+ del items[start:start+slicelength]
else:
n = len(items)
i = start
@@ -662,10 +662,11 @@
while i >= lim:
items[i] = items[i-delta]
i -= 1
- elif start >= 0:
+ elif delta == 0:
+ pass
+ else:
+ assert start >= 0 # start<0 is only possible with slicelength==0
del items[start:start+delta]
- else:
- assert delta==0 # start<0 is only possible with slicelength==0
elif len2 != slicelength: # No resize for extended slices
raise operationerrfmt(space.w_ValueError, "attempt to "
"assign sequence of size %d to extended slice of size %d",
diff --git a/pypy/objspace/std/test/test_bytearrayobject.py b/pypy/objspace/std/test/test_bytearrayobject.py
--- a/pypy/objspace/std/test/test_bytearrayobject.py
+++ b/pypy/objspace/std/test/test_bytearrayobject.py
@@ -1,5 +1,9 @@
+from pypy import conftest
class AppTestBytesArray:
+ def setup_class(cls):
+ cls.w_runappdirect = cls.space.wrap(conftest.option.runappdirect)
+
def test_basics(self):
b = bytearray()
assert type(b) is bytearray
@@ -439,3 +443,15 @@
def test_reduce(self):
assert bytearray('caf\xe9').__reduce__() == (
bytearray, (u'caf\xe9', 'latin-1'), None)
+
+ def test_setitem_slice_performance(self):
+ # because of a complexity bug, this used to take forever on a
+ # translated pypy. On CPython2.6 -A, it takes around 8 seconds.
+ if self.runappdirect:
+ count = 16*1024*1024
+ else:
+ count = 1024
+ b = bytearray(count)
+ for i in range(count):
+ b[i:i+1] = 'y'
+ assert str(b) == 'y' * count
More information about the pypy-commit
mailing list