2014年8月23日土曜日

golang: time.Tick() の精度

time.Tick()がどの程度の精度を持っているか気になったので実行結果を見てみました。
実行環境に依ると思いますが、今回の結果としては、1ms間隔のTickを要求して、平均1023us、標準偏差232usでした。思った以上に精度が悪かったです。
この結果が、golangのタイマーの実装に依るものなのか、OSのタイマーの精度に依るものなのか、までは調べていません。実行環境がLinuxだったので、後者の影響が大きいと思います。

使用した環境

Xubuntu 12.04
go1.3

テストコード

以下のコードtime_precision.goは、1ms間隔のTickを1000回取得して、その平均値を計算しています。
package main

import (
        "fmt"
        "sync"
        "time"
)

const numof_sample = 1000
const interval_millisec = 1

func main() {
        times := make([]time.Time, numof_sample)
        tick := time.Tick(interval_millisec * time.Millisecond)
        var wg sync.WaitGroup

        wg.Add(1)
        go func() {
                for i := 0; i < len(times); i++ {
                        times[i] = <-tick
                }
                wg.Done()
        }()
        wg.Wait()

        ave := int64(0)
        for i := 1; i < len(times); i++ {
                diff := times[i].UnixNano() - times[i-1].UnixNano()
                ave += diff
                fmt.Printf("tick interval: %6d [us]\n", diff/1000)
        }
        ave /= int64(len(times) - 1)
        fmt.Printf("ave: %6d [us]\n", ave/1000)
}

実行結果

$ go run time_precision.go
tick interval:    964 [us]
tick interval:   1002 [us]
tick interval:   1004 [us]
tick interval:    974 [us]
tick interval:    971 [us]
tick interval:   1023 [us]
tick interval:   1024 [us]
tick interval:   1025 [us]
(中略)
tick interval:   1374 [us]
tick interval:    509 [us]
tick interval:   1480 [us]
tick interval:    540 [us]
tick interval:   1684 [us]
tick interval:    337 [us]
tick interval:    929 [us]
ave:   1023 [us]

平均は、1023usでした。
別途標準偏差を計算すると、標準偏差は232usでした。
msオーダではtime.Tick()の精度はあまり期待できないようです。

参考

http://stackoverflow.com/questions/14610459/how-precise-is-gos-time-really
http://d.hatena.ne.jp/naoya/20080122/1200960926

2014年8月1日金曜日

GoでHelloWorld

使用した環境

Xubuntu 12.04
go1.3

インストール

次のURLから自分の環境に合ったバイナリをダウンロードする。
http://golang.org/dl/

解凍
tar xzf go1.3.linux-386.tar.gz

解凍してできたディレクトリgoは、/usr/local/以下に置くか、自分の好きな場所に置くか、どちらかを選ぶ。
/usr/local/以下に置く場合は、$/HOME/.profileでPATHに加えるだけ。
export PATH=$PATH:/usr/local/go/bin

自分の好きな場所に置く場合は、$/HOME/.profileで環境変数GOROOTをexportして、PATHに加える。
export GOROOT=$HOME/go
export PATH=$PATH:$GOROOT/bin

HelloWorld

以下の内容を、hello.goに保存する。
package main

import "fmt"

func main() {
    fmt.Printf("hello, world\n")
}

実行する。
$ go run hello.go
hello, world

参考
http://golang.jp/install
http://golang.org/doc/install