配列内の数値の最小値を求める作業を大量にループさせるコードを書く場面があり、よく使われるminとminimumのどちらがパフォーマンスが良いかを調べたので、結果を記します。
Juliaで配列の最小値を求める方法
Juliaで配列の最小値を求める一番シンプルな方法は、以下の2つです:
- min関数を使う
- minimum関数を使う
min関数とminimum関数の使い方
# min関数 -> 引数に 「"配列"...」を入れる
arr = [4,6,99];
min(arr...) # -> 4
min([-5.3,2,0]...) # -> -5.3
# minimum関数 -> 引数に配列をそのまま入れる
minimum(arr) # -> 4
minimum([-5.3,2,0]) # -> -5.3
min関数よりminimum関数の方が圧倒的に速いです!
どちらを使えばよいか迷って、Juliaの実行時間などのパフォーマンスを計測するパッケージBenchmarkToolsを使って両関数の平均実行時間を調べたところ、min関数よりminimum関数の方が圧倒的に速いことが判明しました。
以下の実験は、100000個の成分を持つ配列b
の最小値を求めるのにmin関数とminimum関数を使った時で実行時間を比較した実験です。
b=rand(100000)
100000-element Vector{Float64}:
0.07661649377719604
0.646703517608999
0.4972175634773961
0.6893494999824146
0.35158611763357195
0.22027202802188928
0.24586562304315396
0.39476733772469186
0.41141803903897145
0.3037154094658425
0.524003104541277
0.6108319260559976
0.3071612199107656
⋮
0.2520123361632036
0.5960248411447657
0.8591244133447207
0.15221420124967233
0.48588096064056074
0.9075623006011952
0.5003984631658029
0.5342887466969424
0.16459541842781045
0.7087452580959306
0.3287200831830004
0.31812125202785935
julia> using BenchmarkTools
julia> @benchmark minimum(b)
BenchmarkTools.Trial:
memory estimate: 16 bytes
allocs estimate: 1
--------------
minimum time: 64.000 μs (0.00% GC)
median time: 66.400 μs (0.00% GC)
mean time: 66.535 μs (0.00% GC)
maximum time: 122.600 μs (0.00% GC)
--------------
samples: 10000
evals/sample: 1
julia> @benchmark min(b...)
BenchmarkTools.Trial:
memory estimate: 5.34 MiB
allocs estimate: 200003
--------------
minimum time: 6.151 ms (0.00% GC)
median time: 7.072 ms (0.00% GC)
mean time: 8.086 ms (4.97% GC)
maximum time: 18.408 ms (28.64% GC)
--------------
samples: 617
evals/sample: 1
このように、minimum関数を使った時は平均時間わずか$66\mu$ sで済んだのに対して、min関数を使った場合は平均約8 msかかっています。その差は100倍以上です。
結論
以上より、配列の最小値を求めるときは、基本的にminimum関数を使うと良いでしょう。