[swift-dev] Implementation of Existential Collection (AnySequence and co.)

Ole Begemann ole at oleb.net
Wed Apr 5 09:00:37 CDT 2017


On 05.04.2017 15:22, Pavol Vaskovic via swift-dev wrote:
> On Wednesday, 5 April 2017 at 14:56, Pavol Vaskovic wrote:
>> Thanks Ole! This explanation of type erasure makes total sense. I have overlooked they are generic over different axis.
>>   
>> But I think I have confirmed the performance implications of this design and created https://bugs.swift.org/browse/SR-4499 to track the issue.
>> As is, all elements that get vended through this are being created using virtual dispatch on generic protocol - super slow.
>>   
>> If I recall correctly, there is alternative approach to type erasure using closures, but its possible it has similar performance characteristics?
> Why exactly isn’t `AnyIterator` implemented like this?
>
> public struct AnyIterator<Element> : IteratorProtocol, Sequence {
> let _next: () -> Element?
> public init<I : IteratorProtocol>(_ base: I) where I.Element == Element {
> var _base = base
> _next = { return _base.next() }
> }
> public init(_ next: @escaping () -> Element?) {
> _next = next
> }
> public func next() -> Element? {
> return _next()
> }
> }
>
>
> It seems to me this is using the same "Methods Constructed in Initializers” pattern I was asking about Re: `_ClosureBasedIterator`.

One reason to favor the class-based approach to type erasure is that the 
closure-based approach requires more storage if the protocol you're 
implementing has multiple methods — the closure-based approach requires 
storage for one closure per method vs. storage for a single reference in 
the class-based approach.

This argument doesn't really apply to AnyIterator since IteratorProtocol 
only defines a single method, though. I'm not sure why the standard 
library prefers the class-based approach.



More information about the swift-dev mailing list