Commit 9116583f authored by Lars Buitinck's avatar Lars Buitinck

optimize general sorted(x) calls

parent ec5df1e0
...@@ -1477,6 +1477,10 @@ class EarlyReplaceBuiltinCalls(Visitor.EnvTransform): ...@@ -1477,6 +1477,10 @@ class EarlyReplaceBuiltinCalls(Visitor.EnvTransform):
gen_expr_node.pos, loop = loop_node, result_node = result_ref, gen_expr_node.pos, loop = loop_node, result_node = result_ref,
expr_scope = gen_expr_node.expr_scope, orig_func = is_any and 'any' or 'all') expr_scope = gen_expr_node.expr_scope, orig_func = is_any and 'any' or 'all')
PySequence_List_func_type = PyrexTypes.CFuncType(
Builtin.list_type,
[PyrexTypes.CFuncTypeArg("it", PyrexTypes.py_object_type, None)])
def _handle_simple_function_sorted(self, node, pos_args): def _handle_simple_function_sorted(self, node, pos_args):
"""Transform sorted(genexpr) and sorted([listcomp]) into """Transform sorted(genexpr) and sorted([listcomp]) into
[listcomp].sort(). CPython just reads the iterable into a [listcomp].sort(). CPython just reads the iterable into a
...@@ -1514,7 +1518,11 @@ class EarlyReplaceBuiltinCalls(Visitor.EnvTransform): ...@@ -1514,7 +1518,11 @@ class EarlyReplaceBuiltinCalls(Visitor.EnvTransform):
expr = pos_args[0].as_list() expr = pos_args[0].as_list()
listcomp_node = loop_node = expr listcomp_node = loop_node = expr
else: else:
return node # Interestingly, PySequence_List works on a lot of non-sequence
# things as well.
listcomp_node = loop_node = ExprNodes.PythonCapiCallNode(
node.pos, "PySequence_List", self.PySequence_List_func_type,
args=pos_args, is_temp=True)
result_node = UtilNodes.ResultRefNode( result_node = UtilNodes.ResultRefNode(
pos = loop_node.pos, type = Builtin.list_type, may_hold_none=False) pos = loop_node.pos, type = Builtin.list_type, may_hold_none=False)
......
cimport cython cimport cython
def generator():
yield 2
yield 1
yield 3
def returns_set():
return set(["foo", "bar", "baz"])
def returns_tuple():
return (1, 2, 3, 0)
@cython.test_fail_if_path_exists("//SimpleCallNode")
def sorted_arg(x):
"""
>>> a = [3, 2, 1]
>>> sorted_arg(a)
[1, 2, 3]
>>> a
[3, 2, 1]
>>> sorted(generator())
[1, 2, 3]
>>> sorted(returns_set())
['bar', 'baz', 'foo']
>>> sorted(returns_tuple())
[0, 1, 2, 3]
>>> sorted(object())
Traceback (most recent call last):
TypeError: 'object' object is not iterable
"""
return sorted(x)
#@cython.test_fail_if_path_exists("//GeneratorExpressionNode", #@cython.test_fail_if_path_exists("//GeneratorExpressionNode",
# "//ComprehensionNode//NoneCheckNode") # "//ComprehensionNode//NoneCheckNode")
#@cython.test_assert_path_exists("//ComprehensionNode") #@cython.test_assert_path_exists("//ComprehensionNode")
...@@ -10,7 +41,7 @@ def sorted_genexp(): ...@@ -10,7 +41,7 @@ def sorted_genexp():
""" """
return sorted(i*i for i in range(10,0,-1)) return sorted(i*i for i in range(10,0,-1))
#@cython.test_assert_path_exists("//SimpleCallNode//SimpleCallNode") @cython.test_assert_path_exists("//SimpleCallNode//SimpleCallNode")
def sorted_list_of_range(): def sorted_list_of_range():
""" """
>>> sorted_list_of_range() >>> sorted_list_of_range()
......
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