4 ms·
The iterator pattern I have in https://github.com/ryszard/goskiplist https://github.com/ryszard/goskiplist uses an interface similar to type Iterator interfa
by szopa 13y ago
The iterator pattern I have in https://github.com/ryszard/goskiplist https://github.com/ryszard/goskiplist uses an interface similar to
type Iterator interface {
// Next returns true if the iterator contains subsequent elements
// and advances its state to the next element if that is possible.
Next() (ok bool)
// Value returns the current value.
Value() interface{}
}
which you then use like this:
iter := s.Iterator()
for iter.Next() {
fmt.Printf("%s\n", iter.Value())
}
I think this is a pretty good pattern: it's concise, looks less ugly than the callback and closure based iterators, and it's not using anything heavyweight like channels, so there should be no significant performance degradation.
Out of curiosity, I added this pattern to OP's test code as StatefulIterator (https://github.com/ewencp/golang-iterators-benchmark/pull/1 https://github.com/ewencp/golang-iterators-benchmark/pull/1), in 2 versions: one in which the iterator is a struct, and one in which the iterator is an interface. The results look like this (the 4 last rows are my additions):
BenchmarkIntsCallbackIterator 500 3478962 ns/op
BenchmarkDataCallbackIterator 500 4437885 ns/op
BenchmarkIntsChannelIterator 10 186095017 ns/op
BenchmarkDataChannelIterator 10 188627451 ns/op
BenchmarkIntsBufferedChannelIterator 20 90941766 ns/op
BenchmarkDataBufferedChannelIterator 20 90175550 ns/op
BenchmarkIntsClosureIterator 500 5580257 ns/op
BenchmarkDataClosureIterator 500 6183472 ns/op
BenchmarkIntStatefulIterator 1000 2653265 ns/op
BenchmarkDataStatefulIterator 500 3582051 ns/op
BenchmarkIntStatefulIteratorInterface 200 7516778 ns/op
BenchmarkDataStatefulIteratorInterface 200 8250702 ns/op
ok _/Users/ryszard/Projects/golang-iterators-benchmark 33.717s
As you can see, the struct version is the fastest of the lot: 2653265 ns for ints and 3582051 ns structs (versus the callback version with 3478962 ns and 4437885 ns, respectively). The interface version is slower, but still in the same ballpark as the callback and closure based ones, while being much more readable (but that's only my personal opinion). The not-so-stellar performance of interfaces is a bit disappointing, but that is a known issue.