インクリメントのタイミングについて

ブラックビスケッツナツカシス

この記事を三行にまとめると

PHPで数値を+1する方法は全部で4つあります
前置インクリメントと後置インクリメント
前置の方が若干処理速度が速いらしいです
ささいな話ではあるのですが、PHPで数値を+1する方法は全部で4つあります。

$i = 1;

//単純な+1
$i = $i + 1;

//+1の省略形
$i += 1;

//前置インクリメント
++$i;

//後置インクリメント
$i++;

上二つに関しては特に問題ないと思います。読んで数式のごとく$iの値が1増えます。

下二つに関しても1増えるという結果は変わらないのですが、実は1増えるタイミングが微妙に違います。

例えば以下のようなコードの場合。

$a = $b = 1;

++$a;
echo $a; // 2

$b++;
echo $b; // 2

この場合はどちらもechoの時点で2が出力されます。

でもインクリメントしている状態の変数を直接echoした場合。

$a = $b = 1;

echo ++$a; // 2

echo $b++; // 1

これだと$aは先ほどと同じように2を出力しますが、$bの方は1が出力されます。

簡単に言うと$aの前置インクリメントの方はインクリメントしてから変数の値をechoするのに対し、$bの後置インクリメントは先に変数の値をechoしてからインクリメントするという処理が内部的に行われています。だから後者の方は1が出力されてしまうんですね。でもインクリメント自体は行われているので、もう一度echoすれば2が出力されます。

どちらにせよインクリメントは行えるから良いじゃんって話ではあるのですが、例えば配列の要素にインクリメントした値を突っ込みたいみたいな時にこの仕様を忘れていると、正しい配列が作成できないかもしれません。

$i = 1;

$a = array(
  1 => $i++,
  2 => ++$i,
);

print_r($a)

//出力結果
Array ( [1] => 1 [2] => 3 )

「++はインクリメント」とだけしか認識していないと上記の書き方でも$a[1]が2になってくれそうに思いますが、これはさっきの「echo $b++」と同じで先に$iの中身が出力されてからインクリメントされるので$a[1]の値は1のままです。

処理の流れ的には「$a[1]の値が1になる → $iがインクリメントされる → $iがインクリメントされる → $a[2]の値が3になる」といった感じです。

配列の要素に直接インクリメント演算子を書く機会ってあまりないような気もするんですが、もしこんなような書き方をしていて「あれ? 値が増えてないぞ?」って思った時は、演算子の位置を後ろから前に持ってくれば解決するかもしれません。



余談ですが前置インクリメントと後置インクリメントでは前置の方が若干処理速度が速いらしいです。

PHPパフォーマンスベンチマーク

つまり少しでもfor文の処理速度を上げたければ変化式を後置より前置にした方が良いってことですね。これはデクリメントの場合でも同じようです。

//前置(こっちの方が速いらしい)
for($i = 0; $i < 10; ++$i) {
  echo $i;
}

//後置
for($i = 0; $i < 10; $i++) {
  echo $i;
}
 もしかしたら何か関連しているかも? 
 みんなからのコメント 
まだコメントはいただけてないみたい……