Juliaでコードの性能を評価、ベンチマークする方法
概要
Juliaを使用する最大の理由が速度とパフォーマンスであるため、工学的に最適化されたコードを書くことは非常に重要である。BenchmarkTools.jlは、使いやすく便利でありながらも正確なパフォーマンス評価のインターフェースを提供する1。
コード
julia> sinpi(0.5), cospi(0.5)
(1.0, 0.0)
julia> sincospi(0.5)
(1.0, 0.0)
例として、sincospiで一度に数値を計算する方法と、sinpiとcospiを別々に使用して計算する方法のパフォーマンスを比較してみよう。
@btime
評価結果から、sincospiはsinpiを一つだけ計算する状況では遅いが、cospiも別途計算するよりは速いことがわかる。このような評価結果は@timeと異なり、一度の実行ではなく自身で繰り返し測定したものであるため、より正確で信頼性がある。
julia> x = rand()
0.49058418112141866
julia> @btime SC = sincospi($x);
7.500 ns (0 allocations: 0 bytes)
julia> @btime S = sinpi($x);
4.500 ns (0 allocations: 0 bytes)
julia> @btime SC = sinpi($x), cospi($x);
8.300 ns (0 allocations: 0 bytes)
ここで変数xの前に$を置く理由は、ベンチマークでxがグローバル変数として参照され、パフォーマンスそのものではなくオーバーヘッドを測定するのを防ぐためである。これにより、xはベンチマークの前に事前に計算され、ベンチマークに使用される。
@benchmark
より詳細なパフォーマンス評価結果を見るためには、@benchmarkマクロを使用する。次のようにヒストグラムを含め、視覚的にも優れた結果分析を出力する。

@time, @elapsedとの違い
@btimeは正確にパフォーマンスを評価する意図を持っているが、@timeは単に時間を測定するだけであり、@elapsedはその時間をFloat64で返すという違いがある。
パフォーマンスが優れたコードを書くために、@timeでコードの実行時間を測る習慣自体は非常に望ましいが2、根本的に@timeはコンパイル時間からあらゆるオーバーヘッドを含んでおり、正直にかかった時間は正確に把握できるものの、コード自体のパフォーマンスを評価するものとは言えない。
全コード
sinpi(0.5), cospi(0.5)
sincospi(0.5)
using BenchmarkTools
x = rand()
@btime SC = sincospi($x);
@btime S = sinpi($x);
@btime SC = sinpi($x), cospi($x);
@benchmark SC = sincospi($x)
@benchmark SC = sinpi($x), cospi($x)
環境
- OS: Windows
- julia: v1.10.0
