Go
test
benchmark
Go4Day 8

【調査中】Goのbenchmarkを使うと環境ごとに結果がバラバラになってしまったので、誰か知恵を貸して欲しい

今回のアドベントカレンダー、他のことを書く予定でいたのですが、不思議な事象に遭遇したのでこちらに的を絞って送ります。
解決してません。率直に言って謎。解決できたら追記します。むしろ誰か詳しい方がいたら教えてください。

今回試したこと

variableやconstを変数に代入するだけのコードを書き、ベンチマークをとりました。

ソースコード

package main

var a0 int64 = 0
var a1 int64 = 1
var b0 int8 = 0
var b1 int8 = 1
const c0 = 0
const c1 = 1
const n = 1048576

func case0() int8 {
    var number int8 = 0
    for i := 0; i < n; i++ {
        number = int8(a0)
        number = int8(a1)
    }
    return number
}

func case1() int8 {
    var number int8 = 0
    for i := 0; i < n; i++ {
        number = b0
        number = b1
    }
    return number
}

func case2() int8 {
    var number int8 = 0
    for i := 0; i < n; i++ {
        number = c0
        number = c1
    }
    return number
}

func case3() int8 {
    var number int8 = 0
    for i := 0; i < n; i++ {
        number = 0
        number = 1
    }
    return number
}

ベンチマークテスト

package main

import "testing"

func BenchmarkCase0(b *testing.B) {
    for i := 0; i < b.N; i++ {
        case0()
    }
}

func BenchmarkCase1(b *testing.B) {
    for i := 0; i < b.N; i++ {
        case1()
    }
}

func BenchmarkCase2(b *testing.B) {
    for i := 0; i < b.N; i++ {
        case2()
    }
}

func BenchmarkCase3(b *testing.B) {
    for i := 0; i < b.N; i++ {
        case3()
    }
}

結果

$ go test -bench . -benchmem
BenchmarkCase0-4        5000        314894 ns/op           0 B/op          0 allocs/op
BenchmarkCase1-4        5000        314963 ns/op           0 B/op          0 allocs/op
BenchmarkCase2-4        2000        636342 ns/op           0 B/op          0 allocs/op
BenchmarkCase3-4        5000        328588 ns/op           0 B/op          0 allocs/op

問題点

結果を見ればわかるように、constだけ2倍近く時間がかかります。constなので、他と同レベルの時間で処理が終わるはず。

補足

  • goのバージョンは1.8.3
  • OSはHigh Sierra 10.13.2
  • 自宅のデスクトップ(ubuntu16.04)で同じコードを動かすと定数が遅い事象は起きない
  • 他のmacで試したいが、アドベントカレンダーの締め切りまでに試せそうな端末がなかった

作業メモはこのページに集約して、こちらでは結果だけ書きます。