変数と配列と連想配列の速度がどの程度違うのか気になったので調べてみた。
テスト方法
テスト方法は、「$x=1」「$y[1]=1」「$z{1}=1」など変数への代入を1秒間中に何回できるかを下記のようなプログラムで実験しました。
ベンチマークプログラム概要。
local($t,$i); local($n1,@n2,%n3,@n4,%n5); local($s1,@s2,%s3,@s4,%s5); $t=time()+2; while(time()<$t){} $t=time()+1; while(time()<$t){ $i++; &num1($i); # ↑ ここを下記のサブルーチンnum1~6とstr1~6に書き換える。 } print "$i 回" #------- sub num1{ my $i=$_[0]; $n1=1; } sub num2{ my $i=$_[0]; $n2[1]=1; } sub num3{ my $i=$_[0]; $n3{1}=1; } sub num4{ my $i=$_[0]; $n4[$i]=1; } sub num5{ my $i=$_[0]; $n5{$i}=1; } sub num6{ my $i=$_[0]; my $n6; $n6=1; } sub str1{ my $i=$_[0]; $s1="1"; } sub str2{ my $i=$_[0]; $s2[1]="1"; } sub str3{ my $i=$_[0]; $s3{1}="1"; } sub str4{ my $i=$_[0]; $s4[$i]="1"; } sub str5{ my $i=$_[0]; $s5{"$i"}="1"; } sub str6{ my $i=$_[0]; my $s6; $s6="1"; }
数列テスト内容と結果
・数列テスト1:スタンダードに「$n1=1;」のみ行う
結果 12354843回
・数列テスト2:配列だが同じ配列に代入「$n2[1]=1;」
結果 11672801回
テスト1を100%とすると94%の効率。
・数列テスト3:連想配列だが同じ配列に代入「$n3{1}=1;」
結果 10303955回
テスト1を100%とすると83%の効率。
・数列テスト4:配列を毎回拡張「$n4[$i]=1;」
結果 9218664回
テスト1を100%とすると74%の効率。
$iの展開があるので妥当な低下。
・数列テスト5:連想配列を毎回拡張「$n5{$i}=1;」
結果 2262218回
テスト1を100%とすると18%の効率。
異常なほど遅い。連想配列は使わない方が良い。
その他、$n5{"$i"}とした場合若干スコアが下がる。
・数列テスト6:変数を毎回myで宣言して代入「$n6=1;」
結果 10881528回
テスト1を100%とすると88%の効率。
このテストは変数が多数ある時、個々に変数を宣言した場合と、連想配列で1回だけ変数宣言して連想配列を使った場合の速度の比較用に計測した。結果は毎回宣言しても配列(テスト4)や連想配列(テスト5)よりも早い。
文字列テスト内容と結果
・文字列テスト1:「$s1="1";」のみ行う
結果 11501568回
数列テスト1を100%とすると93%効率。
やはり文字列操作の方が遅い。
・文字列テスト2:配列だが同じ配列に代入「$s2[1]="1";」
結果 11024590回
テスト1を100%とすると95%の効率。
・文字列テスト3:連想配列だが同じ配列に代入「$s3{1}="1";」
結果 9889949回
テスト1を100%とすると85%の効率。
・文字列テスト4:配列を毎回拡張「$s4[$i]="1";」
結果 6262342回
テスト1を100%とすると54%の効率。
かなり落ち込みが激しい。数列テスト4の時はそれほど低下しなかったのだが・・・。
・文字列テスト5:連想配列を毎回拡張「$s5{$i}="1";」
結果 2097152回
テスト1を100%とすると18%の効率。
数列テスト5と同じく、使い物にならないほど遅い。
・文字列テスト6:変数を毎回myで宣言して代入「$s6="1";」
結果 10204236回
テスト1を100%とすると88%の効率。
まとめ
・速度が速い順に「変数>配列>連想配列」
・文字型と数値型では数値型の方が速い。
・配列や連想配列が増える時の速度低下が大きく、特に連想配列では2割を切る効率しかない。
以上の事から配列の使用は少な目で、連想配列は極力使わないようにするのが良い。
予想通りの順番ではあるが、予想以上に連想配列のパフォーマンスは悪かった。