以下代码在合理的时间内自行编译 EXAMPLE :
public struct LazyProduct6Sequence <
T1: LazySequenceProtocol, T2: LazySequenceProtocol, T3: LazySequenceProtocol,
T4: LazySequenceProtocol, T5: LazySequenceProtocol, T6: LazySequenceProtocol
>: LazySequenceProtocol {
public typealias Element = (T1.Element, T2.Element, T3.Element, T4.Element, T5.Element, T6.Element)
public typealias Iterator = AnyIterator<Element>
private let iterator: Iterator
internal init (
_ sequence1: T1, _ sequence2: T2, _ sequence3: T3,
_ sequence4: T4, _ sequence5: T5, _ sequence6: T6
) {
self.iterator = AnyIterator(
sequence1.flatMap { element1 in
sequence2.flatMap { element2 in
sequence3.flatMap { element3 in
sequence4.flatMap { element4 in
sequence5.flatMap { element5 in
sequence6.map { element6 in
(element1, element2, element3, element4, element5, element6)
}
}
}
}
}
}.makeIterator()
)
}
public func makeIterator () -> Iterator {
return self.iterator
}
}
public func product <
T1: LazySequenceProtocol, T2: LazySequenceProtocol, T3: LazySequenceProtocol,
T4: LazySequenceProtocol, T5: LazySequenceProtocol, T6: LazySequenceProtocol
> (
_ sequence1: T1, _ sequence2: T2, _ sequence3: T3,
_ sequence4: T4, _ sequence5: T5, _ sequence6: T6
) -> LazyProduct6Sequence<T1, T2, T3, T4, T5, T6> {
return LazyProduct6Sequence(sequence1, sequence2, sequence3, sequence4, sequence5, sequence6)
}
但是,在编译使用它的代码时,编译(或完全拒绝编译)需要大约40秒 EXAMPLE :
_ = product([1, 2].lazy, [3, 4].lazy, [5, 6].lazy, [7, 8].lazy, [9, 10].lazy, [11, 12].lazy)
为什么需要花费大量时间进行编译?
答案 0 :(得分:1)
我可以解决这个问题,这与Swift的类型推理系统有关。为每个闭包添加显式返回类型并没有多大帮助,因为编译时间几乎保持不变。但是当我在使用函数 EXAMPLE 的赋值中添加显式类型时,编译几乎是即时的:
let sequence: LazyProduct6Sequence<
LazyRandomAccessCollection<[Int]>,
LazyRandomAccessCollection<[Int]>,
LazyRandomAccessCollection<[Int]>,
LazyRandomAccessCollection<[Int]>,
LazyRandomAccessCollection<[Int]>,
LazyRandomAccessCollection<[Int]>
> = product(
[1, 2].lazy,
[3, 4].lazy,
[5, 6].lazy,
[7, 8].lazy,
[9, 10].lazy,
[11, 12].lazy
)
let iterator = sequence.makeIterator()
while let element = iterator.next() {
print(element)
}
显然这不太理想而且很难看。
我不知道它为什么会发生,因为只有一个函数与表达式匹配。
值得一提的是,对于较低的arities,编译时间会缩短。如果我将product
重载为急切Sequence
,则编译将冻结我的机器。
编辑:我从那以后就发现默认情况下这些类型的Sequence
应该是懒惰的。使用与上面示例中的Swift的zip
相同的命名约定来重写我的函数:
public struct Product6Iterator <Sequence1: Sequence, Sequence2: Sequence, Sequence3: Sequence, Sequence4: Sequence,
Sequence5: Sequence, Sequence6: Sequence>: IteratorProtocol {
public typealias Element = (Sequence1.Element, Sequence2.Element, Sequence3.Element, Sequence4.Element,
Sequence5.Element, Sequence6.Element)
private let iterator: AnyIterator<Element>
internal init (_ sequence1: Sequence1, _ sequence2: Sequence2, _ sequence3: Sequence3, _ sequence4: Sequence4,
_ sequence5: Sequence5, _ sequence6: Sequence6) {
self.iterator = AnyIterator(
sequence1.lazy.flatMap { element1 in
sequence2.lazy.flatMap { element2 in
sequence3.lazy.flatMap { element3 in
sequence4.lazy.flatMap { element4 in
sequence5.lazy.flatMap { element5 in
sequence6.lazy.map { element6 in
(element1, element2, element3, element4, element5, element6)
}
}
}
}
}
}.makeIterator()
)
}
public mutating func next () -> Element? {
return self.iterator.next()
}
}
public struct Product6Sequence <Sequence1: Sequence, Sequence2: Sequence, Sequence3: Sequence, Sequence4: Sequence,
Sequence5: Sequence, Sequence6: Sequence>: Sequence {
public typealias Iterator = Product6Iterator<Sequence1, Sequence2, Sequence3, Sequence4, Sequence5, Sequence6>
public typealias Element = Iterator.Element
private let sequence1: Sequence1
private let sequence2: Sequence2
private let sequence3: Sequence3
private let sequence4: Sequence4
private let sequence5: Sequence5
private let sequence6: Sequence6
internal init (_ sequence1: Sequence1, _ sequence2: Sequence2, _ sequence3: Sequence3, _ sequence4: Sequence4,
_ sequence5: Sequence5, _ sequence6: Sequence6) {
self.sequence1 = sequence1
self.sequence2 = sequence2
self.sequence3 = sequence3
self.sequence4 = sequence4
self.sequence5 = sequence5
self.sequence6 = sequence6
}
public func makeIterator () -> Iterator {
return Iterator(sequence1, sequence2, sequence3, sequence4, sequence5, sequence6)
}
}
public func product <Sequence1: Sequence, Sequence2: Sequence, Sequence3: Sequence, Sequence4: Sequence,
Sequence5: Sequence, Sequence6: Sequence> (_ sequence1: Sequence1, _ sequence2: Sequence2, _ sequence3: Sequence3,
_ sequence4: Sequence4, _ sequence5: Sequence5, _ sequence6: Sequence6) -> Product6Sequence<Sequence1, Sequence2,
Sequence3, Sequence4, Sequence5, Sequence6> {
return sequence1.product(sequence2, sequence3, sequence4, sequence5, sequence6)
}
public extension Sequence {
func product <Sequence2: Sequence, Sequence3: Sequence, Sequence4: Sequence, Sequence5: Sequence,
Sequence6: Sequence> (_ sequence2: Sequence2, _ sequence3: Sequence3, _ sequence4: Sequence4,
_ sequence5: Sequence5, _ sequence6: Sequence6) -> Product6Sequence<Self, Sequence2, Sequence3, Sequence4,
Sequence5, Sequence6> {
return Product6Sequence(self, sequence2, sequence3, sequence4, sequence5, sequence6)
}
}
这个以及其他类似的Sequence
扩展程序可以在我创建的名为SequenceExtensions的库中找到。