Lazy Collections(惰性集合)是Swift 2中引入的一种特殊机制,它允许将对集合的计算推迟到真正需要结果的时刻。最初,标准的集合方法(例如,map,filter)返回完全计算的新集合结果,这在处理大数组或一系列转换时,有时会导致不必要的内存和时间消耗。
问题在于过度创建中间集合。每次调用map或filter都会创建数据的新副本,而在多个转换的情况下,明显降低了程序的性能。
解决方案是使用.lazy属性的惰性集合。Swift将所有操作合并为一条链,仅计算实际访问的元素。
示例代码:
let array = Array(1...1_000_000) let result = array.lazy.filter { $0 % 2 == 0 }.map { $0 * 3 } print(result.prefix(5)) // 只有前5个值会被计算
关键特性:
问题1:let b = a.lazy.map { ... }是否立即返回计算结果?
不,当使用.lazy和map/filter方法时,计算结果仅在实际访问数据时返回(例如,通过for-in,first,reduce)。
示例代码:
let array = [1, 2, 3] let mapped = array.lazy.map { x in print("processing\(x)") return x * 2 } // 在此阶段不会输出任何内容 let first = mapped.first // 现在将开始计算并出现输出
问题2:在.lazy之后可以向原始集合添加新元素,如果稍后访问结果,它也会被处理吗?
不,Lazy Collection反映了创建惰性表示时集合的状态。稍后添加的元素将不会被考虑。
问题3:对小集合(<100个元素)使用.lazy是否有效?
不,对于小集合,惰性计算的收益几乎不可察觉,有时额外的开销对性能产生负面影响。
在项目中,盲目地对所有的map/filter使用了.lazy,即使在小集合上。
优点:
缺点:
在重构大型事务数据库的报告时,仅对真正存在长链转换的函数使用.lazy。
优点:
缺点: