Commit ec5df1e0 authored by Lars Buitinck's avatar Lars Buitinck

optimize sorted([a,b,c]) into PyList_Sort call

parent 16f809e6
...@@ -6556,6 +6556,12 @@ class TupleNode(SequenceNode): ...@@ -6556,6 +6556,12 @@ class TupleNode(SequenceNode):
else: else:
return SequenceNode.coerce_to(self, dst_type, env) return SequenceNode.coerce_to(self, dst_type, env)
def as_list(self):
t = ListNode(self.pos, args=self.args, mult_factor=self.mult_factor)
if isinstance(self.constant_result, tuple):
t.constant_result = list(self.constant_result)
return t
def is_simple(self): def is_simple(self):
# either temp or constant => always simple # either temp or constant => always simple
return True return True
...@@ -6685,6 +6691,9 @@ class ListNode(SequenceNode): ...@@ -6685,6 +6691,9 @@ class ListNode(SequenceNode):
error(self.pos, "Cannot coerce list to type '%s'" % dst_type) error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
return self return self
def as_list(self): # dummy for compatibility with TupleNode
return self
def as_tuple(self): def as_tuple(self):
t = TupleNode(self.pos, args=self.args, mult_factor=self.mult_factor) t = TupleNode(self.pos, args=self.args, mult_factor=self.mult_factor)
if isinstance(self.constant_result, list): if isinstance(self.constant_result, list):
......
...@@ -1508,6 +1508,11 @@ class EarlyReplaceBuiltinCalls(Visitor.EnvTransform): ...@@ -1508,6 +1508,11 @@ class EarlyReplaceBuiltinCalls(Visitor.EnvTransform):
expr_scope = gen_expr_node.expr_scope, expr_scope = gen_expr_node.expr_scope,
has_local_scope = True) has_local_scope = True)
append_node.target = listcomp_node append_node.target = listcomp_node
elif isinstance(pos_args[0], (ExprNodes.ListNode, ExprNodes.TupleNode)):
# sorted([a, b, c]) or sorted((a, b, c)). The result of the latter
# is a list in CPython, so change it into one.
expr = pos_args[0].as_list()
listcomp_node = loop_node = expr
else: else:
return node return node
......
...@@ -48,5 +48,4 @@ pyregr.test_tuple ...@@ -48,5 +48,4 @@ pyregr.test_tuple
# Inlined generators # Inlined generators
all all
any any
builtin_sorted
inlined_generator_expressions inlined_generator_expressions
cimport cython cimport cython
@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")
def sorted_genexp(): def sorted_genexp():
""" """
>>> sorted_genexp() >>> sorted_genexp()
...@@ -11,10 +10,26 @@ def sorted_genexp(): ...@@ -11,10 +10,26 @@ 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(): def sorted_list_of_range():
""" """
>>> sorted_list() >>> sorted_list_of_range()
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
""" """
return sorted(list(range(10,0,-1))) return sorted(list(range(10,0,-1)))
@cython.test_fail_if_path_exists("//SimpleCallNode")
def sorted_list_literal():
"""
>>> sorted_list_literal()
[1, 1, 2, 2, 3, 3]
"""
return sorted([3, 1, 2] * 2)
@cython.test_fail_if_path_exists("//SimpleCallNode")
def sorted_tuple_literal():
"""
>>> sorted_tuple_literal()
[1, 1, 2, 2, 3, 3]
"""
return sorted((1, 3, 2) * 2)
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