I'm implementing a few custom enumerators for my data model, e.g.
struct Land {
// …
let council: Council
let size: Int
}
extension Collection<MyModel> {
func lands(in council: Council, above size: Int) -> [Land] {
guard isEmpty == false else {
return []
}
filter { $0.council == council && $0.size > size }
}
}
Then I thought if the built-in enumerators also takes a shortcut by checking if the collection is empty, then I don't have to do it. And this isn't limited to filter, but all the enumerators in general. For example, the doc for find(where:) says it has complexity of O(n), which mean O(0) if the collection is empty, but what does that mean exactly, does it skip the loop or still start the loop but finish at the very beginning? Is there any benefit for guarding agains empty collection before calling the enumerator?
Any
Collectionimplementation can implement these methods however they like, as long as they are correct.You can go to the Swift GitHub repository to see how each of the built-in collections are implemented.
I will focus on the default implementations of the
CollectionandSequence(whichCollectioninherits) methods in this answer. See CollectionAlgorithms.swift and SequenceAlgorithms.swift.None of the default implementations that involve iteration checks
isEmpty. In theCollectionmethods, iteration is generally implemented like this:If the collection is empty,
startIndexwill be equal toendIndex. Consequently, the loop does not run.For the
Sequencemethods, the only way available to iterate through aSequenceis tomakeIteratorand repeatedly callnext. It is always some form of:Note that a
forloop is basically syntactic sugar for something like the above.nextimplicitly checks for emptiness. If there is no elements, it returns nil. Consequently, the loop does not run. Also note thatSequencedoes not require anisEmptymethod, so these methods cannot check emptiness this way.Whether you classify this as "skip the loop" or "still start the loop but finish at the very beginning" is up to you. Those descriptions are equivalent as far as I'm concerned.