-
Couldn't load subscription status.
- Fork 75
Open
Labels
Milestone
Description
You mention that forEach is more efficient than a regular for loop for BTrees, which isn't really ideal. It's true that it's a lot easier to write an efficient forEach implementation than to write an efficient iterator, but it's possible to write an efficient iterator! As a proof of concept, here's an improved BTreeIterator:
public class BTreeIterator<Key: Comparable, Value>: IteratorProtocol {
public typealias Element = (Key, Value)
typealias Node = BTreeNode<Key, Value>
let node: Node
var iterator: BTreeIterator?
var index = -1
init(root: Node) {
node = root
incrementChildIterator()
}
private func incrementChildIterator() {
index += 1
if !node.isLeaf && index < node.children.count {
iterator = node.children[index].makeIterator()
}
}
public func next() -> Element? {
if let childIterator = iterator {
if let nextElement = childIterator.next() {
return nextElement
}
else {
iterator = nil
return next()
}
}
else {
guard index < node.elements.count else { return nil }
defer { incrementChildIterator() }
return node.elements[index]
}
}
}
My benchmarks show no significant performance difference between for-in and forEach, now. Let me know what you think!