Skip to content

Commit 9fc66f8

Browse files
committed
[mypyc] feat: reuse existing tuple when calling fn(*args)
1 parent db67fac commit 9fc66f8

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

mypyc/irbuild/ll_builder.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,17 @@ def _construct_varargs(
788788
for value, kind, name in args:
789789
if kind == ARG_STAR:
790790
if star_result is None:
791-
star_result = self.new_list_op(star_values, line)
791+
# fast path if star expr is a tuple:
792+
# we can pass the immutable tuple straight into the function call.
793+
if is_tuple_rprimitive(value.type) and (
794+
len(args) == 1 or (len(args) == 2 and args[1][1] == ARG_STAR2)
795+
): # only matches fn(*args) and fn(*args, **kwargs)
796+
# TODO extend this to optimize fn(*args, k=1, **kwargs) case
797+
star_result = value
798+
continue
799+
else:
800+
# TODO optimize this case using the length utils - currently in review
801+
star_result = self.new_list_op(star_values, line)
792802
self.primitive_op(list_extend_op, [star_result, value], line)
793803
elif kind == ARG_STAR2:
794804
if star2_result is None:
@@ -885,9 +895,13 @@ def _construct_varargs(
885895
# tuple. Otherwise create the tuple from the list.
886896
if star_result is None:
887897
star_result = self.new_tuple(star_values, line)
898+
elif is_tuple_rprimitive(star_result.type):
899+
# We're just passing in the tuple
900+
pass
888901
else:
889902
star_result = self.primitive_op(list_tuple_op, [star_result], line)
890903
if has_star2 and star2_result is None:
904+
# TODO: use dict_copy_op for simple cases of **kwargs
891905
star2_result = self._create_dict(star2_keys, star2_values, line)
892906

893907
return star_result, star2_result

0 commit comments

Comments
 (0)