パフォーマンスに関する限り、方法 2 の方が優れています。特に、配列が大きい場合や文字列キーを使用している場合はなおさらです。
どちらの方法も同じ量のメモリを使用しますが、最初の方法では配列を検索する必要があります。この検索はインデックスによって行われますが、ルックアップにはいくらかのオーバーヘッドがあります。
このテスト スクリプトが与えられた場合:
$array = range(1, 1000000);
$start = microtime(true);
foreach($array as $k => $v){
$array[$k] = $v+1;
}
echo "Method 1: ".((microtime(true)-$start));
echo "\n";
$start = microtime(true);
foreach($array as $k => &$v){
$v+=1;
}
echo "Method 2: ".((microtime(true)-$start));
平均出力は
Method 1: 0.72429609298706
Method 2: 0.22671484947205
テストを100万回ではなく10回だけ実行するようにスケールバックすると、次のような結果が得られます
Method 1: 3.504753112793E-5
Method 2: 1.2874603271484E-5
文字列キーを使用すると、パフォーマンスの違いがより顕著になります。だから走っている。
$array = array();
for($x = 0; $x<1000000; $x++){
$array["num".$x] = $x+1;
}
$start = microtime(true);
foreach($array as $k => $v){
$array[$k] = $v+1;
}
echo "Method 1: ".((microtime(true)-$start));
echo "\n";
$start = microtime(true);
foreach($array as $k => &$v){
$v+=1;
}
echo "Method 2: ".((microtime(true)-$start));
のようなパフォーマンスが得られます
Method 1: 0.90371179580688
Method 2: 0.2799870967865
これは、文字列キーによる検索は、配列インデックスよりもオーバーヘッドが大きいためです。
Elias Van Ootegem's Answerで提案されているように、ループが完了した後に参照を設定解除する必要があることにも注意してください。つまりunset($v);
、パフォーマンスの向上は、読みやすさの損失に対して測定する必要があります。