読者です 読者をやめる 読者になる 読者になる

PHPの@によるエラー抑制機能の遅さ

php

PHPで@によるエラー抑制は実行が遅いという話は聞いていましたが、実際にベンチマークを取られた方がいました。

で、この処理が「遅い」という噂やツッコミを度々受けるので調べてみました。

「ほら、そんな気にするほどでも無いよ」という結果を期待していたのですが、、、なんじゃこりゃ。。。
劇遅じゃないですか、これ。

(中略)

細かい処理とはいえ、最大10倍違うわけですから・・・

「@」でエラー抑制すると PHP が遅くなるという噂について : 管理人@Yoski

これは配列のkeyチェックをするコードを対象としているので、@の効果のみによる遅さはよく分かりません。ということで、もっとシンプルに単純な代入のみで比べてみました。

ベンチマークプログラムはこんな感じ。

<?php
require_once 'Benchmark/Timer.php';
define('COUNT', 1000000);

$t = new Benchmark_Timer;

$t->start();
for ($i = 0; $i < COUNT; ++$i) {
    @$a = '1234';
}

$t->setMarker('@finish');

for ($i = 0; $i < COUNT; ++$i) {
    $b = '1234';
}

$t->stop();
$t->display();
?>

php-5.2.5で実行した結果はこんな感じです。

------------------------------------------------------
marker    time index            ex time         perct
------------------------------------------------------
Start     1210323360.32298600   -                0.00%
------------------------------------------------------
@finish   1210323362.32918100   2.006195        69.02%
------------------------------------------------------
Stop      1210323363.22948700   0.900306        30.98%
------------------------------------------------------
total     -                     2.906501       100.00%
------------------------------------------------------

シンプルな代入の場合、倍くらい遅い感じですかね。一行に複数の処理を記述していると、その分遅くなりそうです。

5.3からはarray_get()が入る?

元記事にあるような配列のkeyチェックは、私はarray_val()を使って

<?php
  $b = array_val($a, 'hoge');

のように書きますが、誰もが自分で書いていそうなarray_val()な関数が、5.3からarray_get()として標準関数に入るような記事をずいぶん前に読んだ記憶があります。でもまだマニュアルにもないみたいだし、どうなったんかな。

(22:31追記)

array_get()を標準関数にという話は、一番新しいところでは[PHP-DEV] [PATCH] array_get()で議論がされたあと、またもや放置状態のようです。ifsetor()とか ?: 演算子との絡みで不要論がでてます。確かに

<?php
  $b = ifsetor($a['hoge']);

でE_NOTICEがでないならば、こちらの方が良い気もします。でもifsetorって名前はよくないなー。もう少し短く3文字以内くらいならもっといいのに。