Skip to content

Commit 6ae85ce

Browse files
committed
[Stdlib] Optimize CollectionType.first
For lazy collections, `isEmpty` and `startIndex` may be O(N) operations. The old implementation ended up being potentially O(2N) instead of O(1). In particular, accessing `col.lazy.filter(pred).first` would evaluate the predicate on elements twice, once to determine the result of `isEmpty` and once to determine `startIndex`.
1 parent 6dcb6ef commit 6ae85ce

File tree

1 file changed

+6
-1
lines changed

1 file changed

+6
-1
lines changed

stdlib/public/core/Collection.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,12 @@ extension CollectionType {
262262
///
263263
/// - Complexity: O(1)
264264
public var first: Generator.Element? {
265-
return isEmpty ? nil : self[startIndex]
265+
// NB: Accessing `startIndex` may not be O(1) for some lazy collections,
266+
// so instead of testing `isEmpty` and then returning the first element,
267+
// we'll just rely on the fact that the generator always yields the
268+
// first element first.
269+
var gen = generate()
270+
return gen.next()
266271
}
267272

268273
/// Returns a value less than or equal to the number of elements in

0 commit comments

Comments
 (0)