Skip to content

Instantly share code, notes, and snippets.

@genya0407
Last active July 28, 2018 12:11
Show Gist options
  • Save genya0407/0d225fd98feff11d8aa3ecac6e2f2f42 to your computer and use it in GitHub Desktop.
Save genya0407/0d225fd98feff11d8aa3ecac6e2f2f42 to your computer and use it in GitHub Desktop.
package main
import "math/big"
func main() {
a := big.NewInt(1)
a.Lsh(a, 128)
thousand := big.NewInt(1000)
for i := 0; i < 100000; i++ {
a.Mul(a, thousand)
}
}
package main
import "math/big"
func main() {
a := big.NewInt(1)
a.Lsh(a, 128)
for i := 0; i < 100000; i++ {
a.Mul(a, big.NewInt(1000))
}
}

これはなに

ISUCON7にて優勝した方のブログ(http://ken39arg.hatenablog.com/entry/2017/11/27/153843)によると、

1000回loop内のtotalMilliIsu.Cmpで使っているnew(big.Int).Mul(itemPrice[itemID], big.NewInt(1000)) をloopの外にだしloop内で初期化させないようにする

という修正によって一気にスコアが上昇したとのことだが、 big.NewInt(1000) を再利用すると本当に早くなるのかを検証した。

(言及されていると思われる部分: https://github.com/isucon/isucon7-final/blob/master/webapp/go/src/app/game.go#L442)

ベンチマーク

プログラムの説明

2^128から始めて、1000を100000回掛けるということをする。

2つのファイルの説明

  • a.go
    • 一番最適そうなやつ
  • b.go
    • big.NewInt(1000) を再利用せずに、ループの中で初期化するようにした

結果

./a  0.67s user 0.02s system 101% cpu 0.676 total
./b  0.70s user 0.03s system 97% cpu 0.738 total

big.NewInt(1000) を再利用するかどうかでベンチマークの結果はほとんど変わっていないように見える。

考察

元のブログ記事を見ると、「様々な修正を入れたが効果が現れなかったところ」

./c  1.84s user 0.26s system 126% cpu 1.663 total
package main
import "math/big"
func main() {
a := big.NewInt(1)
a.Lsh(a, 128)
for i := 0; i < 100000; i++ {
a = new(big.Int).Mul(a, big.NewInt(1000))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment