[pypy-commit] pypy default: Also use the same jitdriver for list(generator).
arigo
noreply at buildbot.pypy.org
Tue Nov 1 13:04:22 CET 2011
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r48646:f908d360e53c
Date: 2011-11-01 12:06 +0100
http://bitbucket.org/pypy/pypy/changeset/f908d360e53c/
Log: Also use the same jitdriver for list(generator).
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -781,7 +781,9 @@
# xxx special hack for speed
from pypy.interpreter.generator import GeneratorIterator
if isinstance(w_iterator, GeneratorIterator):
- return w_iterator.unpackiterable()
+ lst_w = []
+ w_iterator.unpack_into(lst_w)
+ return lst_w
# /xxx
return self._unpackiterable_unknown_length(w_iterator, w_iterable)
else:
diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py
--- a/pypy/interpreter/generator.py
+++ b/pypy/interpreter/generator.py
@@ -156,7 +156,7 @@
break
block = block.previous
- def unpackiterable(self):
+ def unpack_into(self, results_w):
"""This is a hack for performance: runs the generator and collects
all produced items in a list."""
# XXX copied and simplified version of send_ex()
@@ -164,10 +164,9 @@
if self.running:
raise OperationError(space.w_ValueError,
space.wrap('generator already executing'))
- results_w = []
frame = self.frame
if frame is None: # already finished
- return results_w
+ return
self.running = True
try:
while True:
@@ -182,7 +181,6 @@
frame.f_backref = jit.vref_None
self.running = False
self.frame = None
- return results_w
jitdriver = jit.JitDriver(greens=['self.pycode'],
reds=['self', 'frame', 'results_w'])
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -54,7 +54,12 @@
def _init_from_iterable(space, items_w, w_iterable):
# in its own function to make the JIT look into init__List
- # XXX this would need a JIT driver somehow?
+ # xxx special hack for speed
+ from pypy.interpreter.generator import GeneratorIterator
+ if isinstance(w_iterable, GeneratorIterator):
+ w_iterable.unpack_into(items_w)
+ return
+ # /xxx
w_iterator = space.iter(w_iterable)
while True:
try:
diff --git a/pypy/objspace/std/test/test_listobject.py b/pypy/objspace/std/test/test_listobject.py
--- a/pypy/objspace/std/test/test_listobject.py
+++ b/pypy/objspace/std/test/test_listobject.py
@@ -801,6 +801,20 @@
l.__delslice__(0, 2)
assert l == [3, 4]
+ def test_list_from_set(self):
+ l = ['a']
+ l.__init__(set('b'))
+ assert l == ['b']
+
+ def test_list_from_generator(self):
+ l = ['a']
+ g = (i*i for i in range(5))
+ l.__init__(g)
+ assert l == [0, 1, 4, 9, 16]
+ l.__init__(g)
+ assert l == []
+ assert list(g) == []
+
class AppTestListFastSubscr:
More information about the pypy-commit
mailing list