Conclusion

from...until is much faster than across... in this release.

With inlining size 10, from...until gains more points.

The proportion of the instructions being iterated influences the result. The result is more close to the fact when the proportion of the instructions being iterated is close to 0%. I can infer when the proportion is large, the difference of from...until and across... can be ignored.

Testing of some of our own local code, which was created using the across loop and then compared with the from loop shows that the across is only slightly slower than the from (e.g. 1.3x to 1.6x and not the 4.5x demonstrated above). We have not performed an extensive or exhaustive test, but our initial conclusion is that the content that the loop is operating on plays some role.

Below is an example of the from-loop version. Below it is the across-loop version.
children: ARRAYED_LIST [C]
-- Access to `internal_children'.
--| This is NOT the managed list of children
--| itself and won't remain current.
local
l_internal_children: like children
l_child: C
do
l_internal_children := internal_children
create Result.make (l_internal_children.count)
from l_internal_children.start until l_internal_children.after loop
l_child := l_internal_children.item
if (not l_child.is_deleted) and then (not is_child_filtered (l_child)) then
Result.extend (l_child)
end
l_internal_children.forth
end
ensure
result_not_internal_children: Result /= internal_children
end

And the across ...
children: ARRAYED_LIST [C]
-- Access to `internal_children'.
--| This is NOT the managed list of children
--| itself and won't remain current.
local
l_internal_children: like children
l_child: C
do
l_internal_children := internal_children
create Result.make (l_internal_children.count)
across l_internal_children as ic_children loop
l_child := ic_children.item
if (not l_child.is_deleted) and then (not is_child_filtered (l_child)) then
Result.extend (l_child)
end
end
ensure
result_not_internal_children: Result /= internal_children
end

As stated, the sample is too small to really get a sense of the differences, but as-is, the differences are not significant when compared to the readability of the code using the two versions of looping: across or from.

Manu(5 years ago 10/4/2013)

It is clear that there is an overhead to using across compared to using a simple loop as it first creates an iterator object. In addition, the iterator calls to traverse are causing more dynamic dispatch than the version of a loop using an container that is not polymorphic. We are working on those aspects to provide iterators where this becomes less of an issue. We believe that for ARRAYED_LIST we can get something that is faster than a traditional loop.

Note that I would not use the output of the profiler to say one is faster than the other, because profiling actually modifies the generated code and thus any potential optimizations. Profiler is a great tool to figure out where things get slower, but not for benchmarking.