Skip to content

Conversation

benthor
Copy link

@benthor benthor commented Jul 21, 2025

This PR is significantly improves default iteration performance for WhereSequences by eliminating a redundant call to .iteratorValue of the underlying sequence. This is relevant in cases of nested calls to .where like in the following naive implementation of the Sieve of Eratosthenes (see #1200) which have to resolve a lot of references to produce a final result.

var seq = 2..2999

while (!seq.isEmpty) {
        var prime=seq.take(1).toList[0]
        System.print(prime)
        seq = seq.where{ |n| n % prime != 0 }
}

With unmodified wren 0.4.0, the above takes about a minute to execute on my machine. With the patch from this PR, execution time drops to 3 seconds.

An attempt to explain this insight: The iterator protocol usually means that a call to iterate() returns the current iterator value, a sort of "key" that can be used to look up a value using a call to iteratorValue(). So iterating over a sequence causes alternating calls to iterator() and iteratorValue() to be made.
In case of the WhereSequence however, the .iterator() method internally already itself calls .iteratorValue() on the underlying sequence to determine if the filter function matches or not. The value can simply be cached and returned on the next call to the iteratorValue() method of the enveloping WhereSequence, rather than patching through to the underlying sequence and calling iteratorValue() again on that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant