Hello,  

I’ve been familiarizing myself with the implementation details of the 
`AnySequence` and related types, because I’ve encountered strange performance 
behavior when using them. I have a few questions as a result. I might also hold 
incorrect assumptions about how Swift works, so please be gentle and educate 
me. Also excuse the lengthy URLs at the bottom — I’ll be linking to the sources 
that are at the tip of the master branch at the moment of this writing, so that 
the links keep working correctly in the future, too.

## Performance of Methods Constructed in Initializers

The `_ClosureBasedIterator` is initialized with a closure that is stored in a 
constant stored property (`let`) and gets forwarded to inside the `func next() 
-> Element?`. [1][] I also find this pattern very useful in my code, but I 
wonder about its cost. If this pattern is used on a struct, the direct dispatch 
should be able to go directly to the underlying implementation, right?

I guess the cost will depend on the type of closure passed in: if it captured 
any references, the whole struct incurs reference counting penalty. Can the 
compiler optimize for closures that don’t capture any references and turn this 
pattern into kind of “compile-time dynamic” constructor, that is equal in 
performance to the struct that has the same method implemented directly?  
Given this pattern is often used in conjunction with generics, does this 
pattern affect the compiler’s ability to specialize?

## `let` vs `var` for closures  

What is the performance implication (impact on eligible compiler optimizations) 
of storing closure in a `var` instead of `let`?

The `_ClosureBasedSequence` stores the escaping closure to 
`_makeUnderlyingIterator` in a var. [2][]
Based on the example of `_ClosureBasedIterator` and given that it is never 
mutated, I believe it should be a `let`.

## Abstract Base Class with Single Concrete Implementation

What is the purpose of having an internal abstract base `class 
_AnyIteratorBoxBase`[3][], that is only inherited by the `internal final class 
_IteratorBox`? [4][] It is used as the type to store the underlying base in the 
`struct AnyIterator`, but the initializers in `AnyIterator` create only 
concrete instances of `_IteratorBox` and the remaining occurrence of 
`_AnyIteratorBoxBase` is as parameter for `internal init` that isn’t used 
anywhere. My search found no other subclasses of `_AnyIteratorBoxBase`, so I 
guess this is not an extension point.

If my understanding of how method dispatch works in Swift is correct, this 
prevents direct dispatch and devolves into table dispatch to the underlying 
base implementation in `public func next() -> Element?`. Or is the compiler 
able to devirtualize this given the two public initializers only use the `final 
class _IteratorBox`?

## Links
[1]: 
https://github.com/apple/swift/blob/29ad714bb77913afb26be7507483f5ff3d167d21/stdlib/public/core/ExistentialCollection.swift.gyb#L107
[2]: 
https://github.com/apple/swift/blob/29ad714bb77913afb26be7507483f5ff3d167d21/stdlib/public/core/ExistentialCollection.swift.gyb#L729
[3]: 
https://github.com/apple/swift/blob/29ad714bb77913afb26be7507483f5ff3d167d21/stdlib/public/core/ExistentialCollection.swift.gyb#L135
[4]: 
https://github.com/apple/swift/blob/29ad714bb77913afb26be7507483f5ff3d167d21/stdlib/public/core/ExistentialCollection.swift.gyb#L148

Best regards
Pavol Vaskovic



_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Reply via email to