PHPでは「ダブルクオートよりもシングルクオートの方が早い」というのは本当か?

PHPではダブルクオートよりもシングルクオートの方が早いという説を見かけます。
元をたどると「dublish.com – Simple Optimization for PHP and MySQL」が発端のようです。

Surrounding your string by ‘ instead of ” will make things interpret a little faster since php looks for variables inside “…” but not inside ‘…’. Of course you can only do this when you don’t need to have variables in the string.

dublish.com – Simple Optimization for PHP and MySQL」より

2006年4月の記事なので、少し古いですね。PHP4系の話かもしれません。

PHPで夢を見るBlog PHP文字出力のパフォーマンス比較について」のページに検証用のコードが紹介されていました。
この検証用コードをレンタルサーバー上で試してみたところ、次のような結果になりました。

なお実行したレンタルサーバーの環境はPHP Version 5.2.14です。

1回目

2回目

テストの「Benchmark: send to page」と「Benchmark: send to output buffer」の違いですが、「Benchmark: send to output buffer」のテストでは毎回 ob_clean(); を実行して出力バッファをクリアしています。

Benchmark: send to page の例

$t1 = new timer();
for($i=0;$i<$iterations;$i++) {
    echo 'Okay. I am going This is data to be concatenated. It is long, so as to make it take longer to concatenate and hence widen the gap between the faster and the slower of the methods. to concatenate the $data string This is data to be concatenated. It is long, so as to make it take longer to concatenate and hence widen the gap between the faster and the slower of the methods. a few times between this sentence. This is data to be concatenated. It is long, so as to make it take longer to concatenate and hence widen the gap between the faster and the slower of the methods.';
}
$t1 = $t1->tick(); if($t1 > $max) $max = $t1;

Benchmark: send to output buffer の例

$t5 = new timer();
for($i=0;$i<$iterations;$i++) {
    echo 'Okay. I am going This is data to be concatenated. It is long, so as to make it take longer to concatenate and hence widen the gap between the faster and the slower of the methods. to concatenate the $data string This is data to be concatenated. It is long, so as to make it take longer to concatenate and hence widen the gap between the faster and the slower of the methods. a few times between this sentence. This is data to be concatenated. It is long, so as to make it take longer to concatenate and hence widen the gap between the faster and the slower of the methods.';
}
$t5 = $t5->tick(); if($t5 > $max) $max = $t5;
ob_clean();

PHPの出力バッファリングの挙動について詳しく知りませんが、「Benchmark: send to page」だと出力用バッファが確保するメモリサイズに影響を受けそうだと思いました。

そこで、試しに「Benchmark: send to page」のテストの実行順を変えて、single quotes→double quotesの順からdouble quotes→single quotesの順にして実行してみたところ、single quotesとdouble quotesの実行時間が正反対になりました。

「Benchmark: send to page」の実行時間は参考にしない方が良さそうです。

「Benchmark: send to output buffer」の結果を見ると、シングルクオートとダブルクオートではほとんど差がないようです。

また文字列の結合は、下のコードの方が速度が速いことがわかります。

echo 'Okay. I am going '.$data.' to concatenate the $data string '.$data.' a few times between this sentence. '.$data;

echo "Okay. I am going $data to concatenate the \$data string $data a few times between this sentence. $data";

ちなみに、Rubyではシングルクオートとダブルクオートは実行スピードに関係ありません。
# Rubyの作者であるまつもと ゆきひろ氏がメーリングリストで発言されています。(Old Nabble – [ruby-list:44595] Re: ’ との ”使い分け)

シングルクオートの方が早いのか、それともダブルクオートと変わらないのか、どなたかPHPのソースコードを確認していただけないでしょうか。

2010年11月15日 追記
コメント欄で教えていただきましたが、Zend optimizerやXCacheのON/OFFを切り替えると、結果が変わるそうです。
どのコードの書き方が最も早いかは、実際の運用環境に合わせて考える必要があるようです。

コメント

  1. 検証環境には、PHPのオプティマイザとか入っているのでしょうか?

  2. 今回の検証に使用したレンタルサーバーはミニム(http://www.minim.jp/)のものです。
    PHPのオプティマイザはよくわからないのですが、phpinfo()の出力結果を見るとわかりますか?

  3. phpinfo()の出力結果の上のほうに、CacheとかOptimizerとかのプラグイン類の情報が出ていると思います。

  4. 私の環境(MacOS X, MAMP)では、Zend optimizerやXCacheのON/OFFを切り替えて再起動すると、結果が変わったりしました。

  5. コメントありがとうございます。

    なるほど。勉強になります。
    Zend Optimizerの設定によって速度が変わってくるので、一概にどの方法が早いとは言えませんね。

    phpinfo()の結果を見ると、Zend Optimizerは見つかりました。
    次のようになっていました。

    Optimization Pass 1 enabled
    Optimization Pass 2 enabled
    Optimization Pass 3 enabled
    Optimization Pass 4 enabled
    Optimization Pass 9 enabled
    Zend Loader     enabled
    License Path    no value
    Obfuscation level  3

    Cacheはないようです。

  6. Pingback: みんな気になる「ダブルクオート vs シングルクオート」速度問題 « 山本隆の開発日誌

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください