YAML パーザのベンチマーク

そろそろポインタいじりにも飽きてきたので Pure LL な世界に戻ろうかと思う今日この頃です。
(pthread extension を書いてみようかと思ったこともあったけど、泥沼に嵌る予感がしたので中止)


思うところあって、Spyc と拙作の LibYAML エクステンションベンチマークをとってみました。


テスト用スクリプト:

<?php
require_once 'Cache/Lite.php';
require_once 'spyc.php5';
dl('yaml.so');

$cache = new Cache_Lite(array('automaticSerialization' => true));
$id = 'yaml';
$file = 'piece-unity-config.yaml';

$t1b = microtime(true);
$yaml1 = Spyc::YAMLLoad($file);
$t1e = microtime(true);

$t2b = microtime(true);
$yaml2 = $cache->get($id);
if (!$yaml2) {
    $yaml2 = Spyc::YAMLLoad($file);
    $cache->save($yaml2, $id);
}
$t2e = microtime(true);

$t3b = microtime(true);
$yaml3 = yaml_parse_file($file, 0);
$t3e = microtime(true);

printf("Spyc             : %s: %0.6fsec?n", md5(serialize($yaml1)), $t1e - $t1b);
printf("Spyc + Cache_Lite: %s: %0.6fsec?n", md5(serialize($yaml2)), $t2e - $t2b);
printf("LibYAML extension: %s: %0.6fsec?n", md5(serialize($yaml3)), $t3e - $t3b);

while (true) {
    fprintf(STDERR, 'remove cache? [y/N]: ');
    $answer = strtolower(trim(fgets(STDIN)));
    if ($answer === '') {
        break;
    }
    switch ($answer) {
        case 'y':
        case 'yes':
            $cache->remove($id);
            break 2;
        case 'n':
        case 'no':
            break 2;
        default:
            fprintf(STDERR, "please answer with yes or no.?n");
    }
}


1回目:

Spyc             : ae13976a84e43da933c38e4590c37502: 0.091928sec
Spyc + Cache_Lite: ae13976a84e43da933c38e4590c37502: 0.072896sec
LibYAML extension: ae13976a84e43da933c38e4590c37502: 0.002963sec

Spyc と LibYAML extension で全く同じ結果が得られていますね。パフォーマンスの差よりも、これが重要です。
あと、なぜかキャッシュされていないにも関わらず、Spyc のみより Cache_Lite を組み合わせたほうが速くなっています。VM 内で何か最適化されているんでしょうか?


2回目以降:

Spyc             : ae13976a84e43da933c38e4590c37502: 0.095469sec
Spyc + Cache_Lite: ae13976a84e43da933c38e4590c37502: 0.001582sec
LibYAML extension: ae13976a84e43da933c38e4590c37502: 0.003048sec

Spyc + Cache_Lite > |2倍| > LibYAML extension > |30倍| > Spyc
となりました。さすがにキャッシュの効果は絶大ですね。Spyc を Web サービスに使うならキャッシュ必須と言えます。
LibYAML extension なら単独でも実用的なパフォーマンスが出ていますが、キャッシュを組み合わせた方が良いのは言うまでもありません。


追記:
上記は Mac OS X 10.4.9/G5/2GHz での結果ですが、Mac OS X 10.4.9/Core2Duo/2.33GHz では、下記のようになりました。
1回目:

Spyc             : ae13976a84e43da933c38e4590c37502: 0.028343sec
Spyc + Cache_Lite: ae13976a84e43da933c38e4590c37502: 0.027631sec
LibYAML extension: ae13976a84e43da933c38e4590c37502: 0.000800sec

2回目以降:

Spyc             : ae13976a84e43da933c38e4590c37502: 0.028613sec
Spyc + Cache_Lite: ae13976a84e43da933c38e4590c37502: 0.000538sec
LibYAML extension: ae13976a84e43da933c38e4590c37502: 0.000799sec

CPU が高速なほど Spyc/LibYAML extension の差は大きく、Spyc + Cache_Lite/LibYAML extension の差は小さくなる傾向があるようです。