Commit 39ca71e4 authored by Stefan Behnel's avatar Stefan Behnel

optimise iteration over dict.keys/values/items() in -3 mode

parent 0dcc26cc
...@@ -73,6 +73,7 @@ class IterationTransform(Visitor.VisitorTransform): ...@@ -73,6 +73,7 @@ class IterationTransform(Visitor.VisitorTransform):
def visit_ModuleNode(self, node): def visit_ModuleNode(self, node):
self.current_scope = node.scope self.current_scope = node.scope
self.module_scope = node.scope
self.visitchildren(node) self.visitchildren(node)
return node return node
...@@ -168,12 +169,13 @@ class IterationTransform(Visitor.VisitorTransform): ...@@ -168,12 +169,13 @@ class IterationTransform(Visitor.VisitorTransform):
dict_obj = function.obj dict_obj = function.obj
method = function.attribute method = function.attribute
is_py3 = self.module_scope.context.language_level >= 3
keys = values = False keys = values = False
if method == 'iterkeys': if method == 'iterkeys' or (is_py3 and method == 'keys'):
keys = True keys = True
elif method == 'itervalues': elif method == 'itervalues' or (is_py3 and method == 'values'):
values = True values = True
elif method == 'iteritems': elif method == 'iteritems' or (is_py3 and method == 'items'):
keys = values = True keys = values = True
else: else:
return node return node
......
# cython: language_level=3 # cython: language_level=3
cimport cython
try: try:
sorted sorted
except NameError: except NameError:
...@@ -74,3 +76,26 @@ def dict_comp(): ...@@ -74,3 +76,26 @@ def dict_comp():
result = {x:x*2 for x in range(5) if x % 2 == 0} result = {x:x*2 for x in range(5) if x % 2 == 0}
assert x == 'abc' # don't leak assert x == 'abc' # don't leak
return result return result
# in Python 3, d.keys/values/items() are the iteration methods
@cython.test_assert_path_exists(
"//WhileStatNode",
"//WhileStatNode/SimpleCallNode",
"//WhileStatNode/SimpleCallNode/NameNode")
@cython.test_fail_if_path_exists(
"//ForInStatNode")
def dict_iter(dict d):
"""
>>> d = {'a' : 1, 'b' : 2, 'c' : 3}
>>> keys, values, items = dict_iter(d)
>>> sorted(keys)
['a', 'b', 'c']
>>> sorted(values)
[1, 2, 3]
>>> sorted(items)
[('a', 1), ('b', 2), ('c', 3)]
"""
keys = [ key for key in d.keys() ]
values = [ value for value in d.values() ]
items = [ item for item in d.items() ]
return keys, values, items
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment