file_get_contents()と readfile() をベンチで比較してみた

PHPでファイルの中身をそのまま出力する際に、file_get_contents() を使う場合と readfile() を使う場合があって、あんまり考えてなかったのだけど、改めて調べてみた。

単純に比較してもよく分からなかったので、PHPで簡単にベンチとるならUbenchがよさげ で紹介されていたUbench を使ってみる。と言うかこちらが本筋。

後述ようなプログラムを実行してみた結果は以下。100MB程度のファイルを100ほど出力してみたら、実行時間で10倍ほど、ピーク時のメモリで500倍ほど違うらしい。まぁ、実際の例でここまで顕著な差がでるかどうかは別として、気にするべきポイントということがわかった。めでたしめでたし。

$ php bench.php > /dev/null

trial num: 100

function: readfile();
time : 1.501s
memory peak : 256.00Kb
memory usage: 256.00Kb

function: file_get_contents();
time : 18.372s
memory peak : 104.00Mb
memory usage: 256.00Kb

あとUbenchも手軽に使えるのは良い感じだった。まぁ試行回数を設定できたりすると一々for文を書かなくてもよかったりするんだろうけど、プログラムの途中に埋め込んで単純に速度やらを図る分なら便利に使えそう。

ベンチマーク確認用プログラム

<?php
require_once("Ubench.php");
define("BENCH_NUM", 100);
$file = "file.zip"; // ファイルサイズは 104MB
$stderr = fopen( 'php://stderr', 'w' );
$bench = new Ubench;
fwrite( $stderr, "trial num: " . BENCH_NUM . "\n\n");
fwrite( $stderr, "\n" );
fwrite( $stderr, "function: readfile(); \n");
$result = $bench->run("bench_readfile", $file);
fwrite( $stderr, "time        : " . $bench->getTime() . "\n" );
fwrite( $stderr, "memory peak : " . $bench->getMemoryPeak() . "\n" );
fwrite( $stderr, "memory usage: " . $bench->getMemoryUsage() . "\n" );
fwrite( $stderr, "\n" );
fwrite( $stderr, "function: file_get_contents(); \n");
$result = $bench->run("bench_file_get_contents", $file);
fwrite( $stderr, "time        : " . $bench->getTime() . "\n" );
fwrite( $stderr, "memory peak : " . $bench->getMemoryPeak() . "\n" );
fwrite( $stderr, "memory usage: " . $bench->getMemoryUsage() . "\n" );
function bench_file_get_contents($file) {
for($i = 0; $i < BENCH_NUM; $i++) {
print file_get_contents($file);
}
}
function bench_readfile($file) {
for($i = 0; $i < BENCH_NUM; $i++) {
readfile($file);
}
}