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