はじめに
ネタがないので他の人の書いた面白い記事に乗っかります。
記事の内容を要約すると、
二重配列へのアクセス順序を外側から最初にアップデートするのか、それとも内側からアップデートするか変更することでパフォーマンスに大きな違いが出るとのことでした。
CPU は必要なデータがあるたびにメモリをデータを読み込みにいきます。ただし、CPU からメモリは非常に遠くに存在する上に、メモリの速度よりも CPU の速度の方が圧倒的に速いため、毎回メモリに値をアクセスすると非常に遅くなってしまいます。
Crystalでもやってみた
上の記事のコードをChatGPTの力を借りて、Crystalに翻訳してみました。そしてベンチマークをとってみました。
require "benchmark"
# 配列の初期化
array1 = Array.new(10000) { Array.new(10000, 1) }
array2 = Array.new(10000) { Array.new(10000, 2) }
def method1(array1, array2)
(0...10000).each do |j|
(0...10000).each do |i|
array1[j][i] = array2[j][i]
end
end
end
def method2(array1, array2)
(0...10000).each do |i|
(0...10000).each do |j|
array1[j][i] = array2[j][i]
end
end
end
Benchmark.bm do |x|
x.report("method1:") do
method1(array1.clone, array2)
end
x.report("method2:") do
method2(array1.clone, array2)
end
end
clone
の部分が気になる方もいるかもしれませんが、Crystalでは clone
はディープコピー、dup
はシャローコピーとなります。
結果です。
--release
をつけない場合で
user system total real
method1: 3.721720 0.170310 3.892030 ( 3.876282)
method2: 15.440656 0.016409 15.457065 ( 15.455674)
--release
をつけた場合で
user system total real
method1: 0.275252 0.150778 0.426030 ( 0.406678)
method2: 2.372106 0.000000 2.372106 ( 2.367528)
となり、いずれのケースでも目に見えて大きな差があることがわかります。
予想通りの結果ですが面白いですね。
この記事は以上です。