【Golang】改めてベンチマークの測り方を考える

Hiroki Kojima
Dec 15, 2018 · 4 min read

こんにちは。エウレカAPIチームの小島です。

2018年も残すところ後少しとなりましたが、皆さんいかがお過ごしでしょうか。僕は残りの営業日に怯えながら今年中のタスクをこなす毎日を過ごしています。

そんな話はさておき、普段のコードを書いていく中でどうしても気になってしまうコードの実行速度。Golangはベンチマークが簡単に取れるのでなおさら色々やって計測してみたくなると思います。

そんなベンチマークですが、ふと昔のコードを見返していたところベンチマークの書き方について色々思うところがあったのでまとめて書いてみました。

今回mapとsliceどちらが速いのかを計測する以下のコードを題材にしてみようと思います。

上記コードの実行結果は以下になります。

BenchmarkSlice-4 200000 11172 ns/op
BenchmarkMap-4 100000 13820 ns/op

一度計測したいだけなら上記のコードでもよいのですが、基本的にベンチマークを取る際は利用するケースになるべく近い状態で取ることがベストだと思います。そこで以下の観点が重要になってきます。

  • 条件を変えてのテストがしやすいか
  • 比較しやすいか
  • 比較条件は公平か

上記を踏まえて以下の様なコードにしました。

それぞれ説明していきます。

条件を変えてのテストがしやすいか

簡単に説明してしまうと通常のテスト同様にテーブルテスト形式でケースを複数用意し、for文で回して条件を変えてテストができるように引数を追加しています。

mapとsliceの話でいうとそれぞれのデータの数によりデータを取得する際のアクセス速度が違ってきます。ちなみにどう変わるかというと件数が少ない場合にはsliceが速いのですが、mapはデータ件数が大きくなってきても大きく速度が変わらない性質があります。そのため、件数によってどちらが速いか遅いかが変わります。なので少ない場合と多い場合のテストや、閾値がどこなのかを探るためにも複数条件でテストがかけるようにしておくことが望ましいです。

比較しやすいか

こちらも簡単な話で結果の並び順の問題だと思います。テーブルテストにしたことでケース毎の順番を入れ替えられるようにしています。BenchmarkSliceMap の中に書いてあるように b.Run を利用することで1つの関数内で複数のベンチマークを実行できるようになります。実行箇所を一箇所に集めることで実行時にわかりやすい表示になるように、また実行順序を入れ替えやすいようにしています。

比較条件は公平か

sliceとmapでデータ作成とデータ取得を計測したい場合は最初に上げた例でも条件は公平になっていると思うのですが、取得時の差を取りたい場合は、データ作成の時間も含まれてしまっているため純粋に取得時間だけを測ることができておらず、データ作成に時間が掛かる分mapの方が遅くなり、公平ではありません

これを解消するために b.ResetTimer() を使用します。比較したいロジックの前で呼ぶことでそれまでにかかった時間をなかったコトにします。データ作成後かつデータ取得前に入れることでデータ作成にかかる時間を含めず計測することができます。

特にプロダクションコードを計測する場合などは計測がしやすいコードを事前に書いておく必要があります。これはテストしやすいコードとも言えるので詳細は割愛します。

最後に

まとめて書いてみると思ったよりも当たり前の内容だなと自分でも思ったのですが、自分の書いたコードでも結構多く、見落としている方も多いようにおもいます。

今回1ケースで考えたので足りない、違うなどあるかもしれませんが何かあればご意見お待ちしています。

また弊社では一ヶ月に一回Goもくもく会を開催しております。基本的に各自の作業するだけでなく、LT等簡単なイベントも少々考えているので、もしよろしければご参加くだいさい。

Eureka Engineering

Learn about Eureka’s engineering efforts, product developments and more.

Thanks to Kentaro Takahashi.

Hiroki Kojima

Written by

Pairsのweb版開発を担当しています。 主にバックエンドですが、フロントも少しやってます。 Androidが好きで学生時代からAndroidアプリ開発をやっていましたが、気がついたらなぜかwebエンジニアになってました。 最近はElasticsearchが好きです

Eureka Engineering

Learn about Eureka’s engineering efforts, product developments and more.