1回戦、 Goutte は Simple HTML DOM Parser 相手に、平均0.2s程度の差をつけて、勝利しました。(参考:PHPでスクレイピング【Goutte vs. Simple HTML DOM Parser】)
勝利を称える声の中、ある強者の噂を私は耳にしました。
[引用]機能性ではちょっと劣りますが、パフォーマンス最優先ならpreg_match 関数PHPネイティブの DOMこういった選択肢もアリでしょうね。
たしかに。パフォーマンスを比べるならば、間違いなくオリジナルの関数の速度に勝つ事はないでしょう。
ですが、私のような初心者が組んだ一例として、Goutteの速度を上回ることが難しい例を紹介します。
そこで、2回戦として、 Goutte vs. preg_match vs. DOM でパフォーマンスバトルを行います。
1回戦と同じく、「SayMove!のランキングページから、動画のタイトルを取得する」でベンチマーク対決していただきます。
0, Goutteのベンチコート
時間帯によって差が生まれるので、今回も計測しなおします。
ソースコードはこの前と同じソースコードを使用します。
(参考: gist.github.com/soarcreator/11494901#file-file1-php)
平均実行時間: 0.57205934524536 でした。
1, preg_matchのベンチコート
1-1, 実装
<?php
header('Content-Type: text/html; charset=utf-8');
$kNumberOfSamples = 10; // 何回サンプリングするか
$titles = array();
$totalOfTime = 0;
for ($i = 0; $i < $kNumberOfSamples; ++$i)
{
// 計測を開始する
$startTime = microtime(true);
// ランキングにある全てのタイトルを取得する
$html = file_get_contents('http://say-move.org/ranking.php');
if (preg_match_all('/<h3[\s]class="ranking_ttl"><[^>]*>(.*?)<[^>]*><\/h3>/s', $html, $elements))
{
$rank = 0;
foreach ($elements[1] as $title)
{
$titles[$rank++] = $title;
}
// 解放する
unset($elements);
unset($title);
}
else
{
echo 'Not Found';
}
// 計測を終了する
$totalOfTime += microtime(true) - $startTime;
echo $totalOfTime . '<br/>';
}
print_r($titles);
echo '<br/>平均実行時間: ' . $totalOfTime / $kNumberOfSamples;
unset($titles);
?>
正規表現わからないなりに頑張りましたが、効率が悪かったら、すいません。
1-2, 計測結果
0.69346404075623
1.3898799419403
2.0906138420105
2.7815208435059
3.479859828949
4.1586039066315
4.8545868396759
5.5568058490753
6.2275168895721
6.9227838516235
Array ( [0] => 【映画】THE GREY 凍える太陽 (吹替え)・・略・・[29] => ブラマヨとゆかいな仲間たち アツアツっ )
平均実行時間: 0.69227838516235
なななんと!
PHPのスタンダード正規表現APIが、Goutteより遅いことがわかりました!
2, DOMのベンチマーク
2-1, 実装
とりあえず、途中まで実装しましたが、
<?php
header('Content-Type: text/html; charset=utf-8');
$kNumberOfSamples = 10; // 何回サンプリングするか
$titles = array();
$totalOfTime = 0;
for ($i = 0; $i < $kNumberOfSamples; ++$i)
{
// 計測を開始する
$startTime = microtime(true);
// ランキングにある全てのタイトルを取得する
$html = new DOMDocument();
$html->loadHTMLFile('http://say-move.org/ranking.php');
// 計測を終了する
$totalOfTime += microtime(true) - $startTime;
echo $totalOfTime . '<br/>';
}
print_r($titles);
echo '<br/>平均実行時間: ' . $totalOfTime / $kNumberOfSamples;
unset($titles);
?>
2-2, 計測結果
この時点で、
0.69660210609436
1.3984050750732
2.1059851646423
2.8011412620544
3.4911031723022
4.1912860870361
4.9223821163177
5.6201391220093
6.3140251636505
7.0278391838074
Array ( )
平均実行時間: 0.70278391838074
と遅いので、以降実装をするのをやめました。
a. 結論
私の書いたコードではGoutteがとりあえず速かったのですが、当然GoutteはStandard APIで実装されていますから、もっと頑張れば必ずStandard APIが勝利するでしょう。
Goutteが内部で何をしているかは、本記事では、明らかにしませんが、オープンソースなので、ダウンロードすれば読むことができます。
Goutteのダウンロード&導入方法などは一つ前の記事に書いてあります。よろしければお読み下さい。