Commit 6c9398f8 authored by Stefan Behnel's avatar Stefan Behnel

optimise set([x,y,z]) into a set literal

--HG--
extra : rebase_source : 55b0537a6e3c5a410956fb55e2dafc2bf8b30439
parent 7932ecf3
...@@ -1957,6 +1957,27 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform): ...@@ -1957,6 +1957,27 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
exception_value = "((double)-1)", exception_value = "((double)-1)",
exception_check = True) exception_check = True)
def _handle_simple_function_set(self, node, pos_args):
if len(pos_args) == 1 and isinstance(pos_args[0], (ExprNodes.ListNode,
ExprNodes.TupleNode)):
# We can optimise set([x,y,z]) safely into a set literal,
# but only if we create all items before adding them -
# adding an item may raise an exception if it is not
# hashable, but creating the later items may have
# side-effects.
args = []
temps = []
for arg in pos_args[0].args:
if not arg.is_simple():
arg = UtilNodes.LetRefNode(arg)
temps.append(arg)
args.append(arg)
result = ExprNodes.SetNode(node.pos, is_temp=1, args=args)
for temp in temps[::-1]:
result = UtilNodes.EvalWithTempExprNode(temp, result)
return result
return node
def _handle_simple_function_float(self, node, pos_args): def _handle_simple_function_float(self, node, pos_args):
"""Transform float() into either a C type cast or a faster C """Transform float() into either a C type cast or a faster C
function call. function call.
......
...@@ -123,6 +123,30 @@ def test_set_sideeffect_unhashable_failure(): ...@@ -123,6 +123,30 @@ def test_set_sideeffect_unhashable_failure():
else: assert False, "expected exception not raised" else: assert False, "expected exception not raised"
return L return L
@cython.test_assert_path_exists("//SetNode")
@cython.test_fail_if_path_exists("//SimpleCallNode")
def test_set_of_list():
"""
>>> s = test_set_of_list()
>>> isinstance(s, _set)
True
>>> sorted(s)
[1, 2, 3]
"""
return set([1, 2, 3])
@cython.test_assert_path_exists("//SetNode")
@cython.test_fail_if_path_exists("//SimpleCallNode")
def test_set_of_tuple():
"""
>>> s = test_set_of_tuple()
>>> isinstance(s, _set)
True
>>> sorted(s)
[1, 2, 3]
"""
return set([1, 2, 3])
def sorted(it): def sorted(it):
# Py3 can't compare strings to ints # Py3 can't compare strings to ints
chars = [] chars = []
......
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