Commit ed8aac8a authored by Robert Bradshaw's avatar Robert Bradshaw

Allow pointer target in C array slice iteration to avoid expensive copying.

parent 7e01eaac
...@@ -4349,7 +4349,12 @@ class ForInStatNode(LoopNode, StatNode): ...@@ -4349,7 +4349,12 @@ class ForInStatNode(LoopNode, StatNode):
self.target.analyse_target_types(env) self.target.analyse_target_types(env)
self.iterator.analyse_expressions(env) self.iterator.analyse_expressions(env)
self.item = ExprNodes.NextNode(self.iterator, env) self.item = ExprNodes.NextNode(self.iterator, env)
self.item = self.item.coerce_to(self.target.type, env) if (self.iterator.type.is_ptr or self.iterator.type.is_array) and \
self.target.type.assignable_from(self.iterator.type):
# C array slice optimization.
pass
else:
self.item = self.item.coerce_to(self.target.type, env)
self.body.analyse_expressions(env) self.body.analyse_expressions(env)
if self.else_clause: if self.else_clause:
self.else_clause.analyse_expressions(env) self.else_clause.analyse_expressions(env)
......
...@@ -375,6 +375,9 @@ class IterationTransform(Visitor.VisitorTransform): ...@@ -375,6 +375,9 @@ class IterationTransform(Visitor.VisitorTransform):
base=counter_temp, base=counter_temp,
type=Builtin.bytes_type, type=Builtin.bytes_type,
is_temp=1) is_temp=1)
elif node.target.type.is_ptr and not node.target.type.assignable_from(ptr_type.base_type):
# Allow iteration with pointer target to avoid copy.
target_value = counter_temp
else: else:
target_value = ExprNodes.IndexNode( target_value = ExprNodes.IndexNode(
node.target.pos, node.target.pos,
......
...@@ -217,3 +217,19 @@ def iter_doublearray_for_loop_c(): ...@@ -217,3 +217,19 @@ def iter_doublearray_for_loop_c():
""" """
cdef double d cdef double d
print [ d for d in cdoubles ] print [ d for d in cdoubles ]
cdef struct MyStruct:
int i
def struct_ptr_iter():
"""
>>> struct_ptr_iter()
([0, 1, 2, 3, 4], [0, 1, 2, 3, 4])
"""
cdef MyStruct my_structs[5]
for i in range(5):
my_structs[i].i = i
cdef MyStruct value
cdef MyStruct *ptr
return [ value.i for value in my_structs[:5] ], [ ptr.i for ptr in my_structs[:5] ]
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