LoginSignup
12
11

More than 5 years have passed since last update.

Go で Iterator を書く

Last updated at Posted at 2015-02-15

golangでのイテレーターの実装方法を
ググって見つけたのがこちらの記事
http://ewencp.org/blog/golang-iterators/
こちらにある4種類の方法が主な方法かと思いますが、
気に入ったのは、
チャンネルを使ったパターンとコールバックを使ったパターンの2つ。

チャンネルパターン

コードの書き方としては、
このパターンが一番しっくりくるのですが、、

チャンネルパターン
func IntChannelIterator() <-chan int {
    ch := make(chan int)
    go func() {
        for _, val := range int_data {
            ch <- val
        }
        close(ch) // Remember to close or the loop never ends!
    }()
    return ch
}
チャンネルパターン使用例
var sum int = 0
for val := range IntChannelIterator() {
    sum += val
}

他のパターンと比べると致命的に遅いのが欠点です。
以下は、上記ページにあったコードをgo ver1.4.1を使って
MacBook Pro (Retina, Mid 2012) で実測結果です。

$ go version
go version go1.4.1 darwin/amd64
$ go test -bench .
testing: warning: no tests to run
PASS
BenchmarkIntsCallbackIterator        500       2733180 ns/op
BenchmarkDataCallbackIterator        500       3142514 ns/op
BenchmarkIntsChannelIterator           5     269527633 ns/op
BenchmarkDataChannelIterator           5     266374326 ns/op
BenchmarkIntsBufferedChannelIterator          20      94554939 ns/op
BenchmarkDataBufferedChannelIterator          20      93447309 ns/op
BenchmarkIntsClosureIterator         300       5030297 ns/op
BenchmarkDataClosureIterator         300       4855251 ns/op
BenchmarkIntStatefulIterator        1000       2333693 ns/op
BenchmarkDataStatefulIterator        500       2490458 ns/op
BenchmarkIntStatefulIteratorInterface        200       6054515 ns/op
BenchmarkDataStatefulIteratorInterface       200       6797890 ns/op
ok      github.com/masahide/golang-iterators-benchmark  26.820s

ここまで速度差が出てしまうと、繰り返し処理としては致命的かもしれません。。
チャンネルバッファを使ってもまだまだ・・・。

コールバックパターン

そこで、速さと、コードの書きやすさを両立したコールバックパターンです。

コールバックパターン
func IntCallbackIterator(cb func(int)) {
    for _, val := range int_data {
        cb(val)
    }
}
コールバックパターンの使用例
var sum int = 0
IntCallbackIterator(func(val int) {
    sum += val
})

その他のパターン

なんというか中途半端感があって興味が出ません。。
スピードにこだわるならStatefulパターンですね。でもコールバックとそれほど違わないので、うーん。

12
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
11