blog.ishinao.net

66月/06

serializeとvar_exportどちらが速いのか

Spycでパースしたデータを、serializeしてキャッシュするよりも、var_export($data, true)でPHPコードにしてキャッシュした方が速いんじゃね。と思ってベンチを取ってみた。

using Spyc::YAMLLoad
start: 1149596540.0295
end: 1149596555.4353
elapsed: 15.405829191208
using serialize
start: 1149596555.4358
end: 1149596555.64
elapsed: 0.2041699886322
using php var_export
start: 1149596555.642
end: 1149596556.2202
elapsed: 0.57813310623169

あれー、PHPコードにするよりもserializeの方が速いのか。まあ確かにserializeの方が圧倒的にロジックが単純で済むしな。ただPHPコードとしてファイルに落としておけば、PHP Accelerator系のキャッシュが使えるだろうから、そういうのと組み合わせると速くなるかもしれない。けどまあ、ふつうはserializeを使おう。

一応コード

require_once 'spyc.php';
$yamlFile= 'spyc.yml';
echo "using Spyc::YAMLLoad\n";
$starttime = microtime(true);
for ($i = 0; $i < 1000; $i ++) {
$config = Spyc::YAMLLoad($yamlFile);
}
$endtime = microtime(true);
$elapsedtime = $endtime - $starttime;
echo "start: $starttime\n";
echo "end: $endtime\n";
echo "elapsed: $elapsedtime\n";
echo "\n";
echo "using serialize\n";
$serializedFile = 'spyc.yml.txt';
file_put_contents($serializedFile, serialize($config));
$starttime = microtime(true);
for ($i = 0; $i < 1000; $i ++) {
$config = unserialize(file_get_contents($serializedFile));
}
$endtime = microtime(true);
$elapsedtime = $endtime - $starttime;
echo "start: $starttime\n";
echo "end: $endtime\n";
echo "elapsed: $elapsedtime\n";
echo "\n";
echo "using php var_export\n";
$phpFile = 'spyc.yml.php';
file_put_contents($phpFile, '<?php return ' . var_export($config, true) . '?>');
$starttime = microtime(true);
for ($i = 0; $i < 1000; $i ++) {
$config = include $phpFile;
}
$endtime = microtime(true);
$elapsedtime = $endtime - $starttime;
echo "start: $starttime\n";
echo "end: $endtime\n";
echo "elapsed: $elapsedtime\n";
このエントリーを含むはてなブックマークはてなブックマーク - serializeとvar_exportどちらが速いのか Share on Tumblr このエントリをつぶやくこのWebページのtweets
Filed under: 日記 No Comments
66月/06

配列が絡んだ__setの挙動

class Foo
{
protected $_array = array();
public function __get($name)
{
echo "__get called by $name\n";
switch ($name) {
case 'array': return $this->_array;
default:
throw new Exception();
}
}
public function __set($name, $value)
{
echo "__set called by $name, $value\n";
switch ($name) {
case 'array':
$this->_array = $value;
break;
default:
throw new Exception();
}
}
}
$foo = new Foo();
var_dump($foo->array);
$foo->array = array(1);
var_dump($foo->array);
$foo->array[] = 2;
var_dump($foo->array);

が、

__get called by array
array(0) {
}
__set called by array, Array
__get called by array
array(1) {
[0]=>
int(1)
}
__get called by array
__get called by array
array(2) {
[0]=>
int(1)
[1]=>
int(2)
}

ってなる(PHP 5.1.4/Windows XP Professional)のは正しいのか?

$foo->array[] = 2;

のところで__setが呼ばれずに、直接Foo::$_arrayに追加されているんだけど。

っつーか、

$foo->array[] = 2;

$tmp = $foo->array;
array_push($tmp, 2);
$foo->array = $tmp;

相当の処理だと信じていたんだけど。

このエントリーを含むはてなブックマークはてなブックマーク - 配列が絡んだ__setの挙動 Share on Tumblr このエントリをつぶやくこのWebページのtweets
Filed under: 日記 No Comments
66月/06

spycのパースって重いんだな

8kバイト+1kバイトのYAMLで書かれた設定ファイルをspycを使って
読み込むWebアプリ。当初の速度はこんな感じ。

Requests per second:    3.01 [#/sec] (mean)
Time per request:       1662.891 [ms] (mean)
Time per request:       332.578 [ms] (mean, across all concurrent requests)

ページ(データ取得+レンダリング)キャッシュをかましてみたんだけど、大して速くならなかった。

Requests per second:    3.67 [#/sec] (mean)
Time per request:       1361.458 [ms] (mean)
Time per request:       272.292 [ms] (mean, across all concurrent requests)

で、YAMLファイルの読み込みにキャッシュ(serializeして保存)をかましたら、劇的に速くなった。

Requests per second:    10.59 [#/sec] (mean)
Time per request:       472.179 [ms] (mean)
Time per request:       94.436 [ms] (mean, across all concurrent requests)

spycのパースってこんなに重い処理だったのか。

このエントリーを含むはてなブックマークはてなブックマーク - spycのパースって重いんだな Share on Tumblr このエントリをつぶやくこのWebページのtweets
Filed under: 日記 No Comments
66月/06

Zendネームスペースの下に入れるのはやめた

Zend_Search_HyperEstraierとして作りかけていたライブラリは、ひとまず単体のライブラリとしての完成度を高める方に集中するために、Zendネームスペース以下で構築するのは(他にやらなきゃならないことが増えるんで)いったんやめて、単にHyperEstraierネームスペース以下に構築することにした。いまいち使う気にならないLucene対抗にしようかと思ってたんだけど。

で、検索条件周りをいろいろいじっているうちに、HyperEstraier_SearchCondition::toQueryStringでノードAPIのパラメータになり、HyperEstraier_SearchCondition::to***(未定)Stringでestcmdのコマンドラインパラメータとなるのが妥当だよなーと思いつつ、そうなるとescmdのラッパーもないと意味がないよなーってことになり、そうなるといったいどこまで作ると一段落ってことになるのか先が見えなくなってきたのでした。

そういや検索条件をもっと設定しやすくしよう計画に関しては、一番わかりにくいのは属性検索の条件式表現だと思うんで、属性検索条件をセットする場合は、

$condition->addAttribute('@title', '==', 'foo');
$condition->addAttribute('@mtime', '>=', '2006/6/6');

とかやると、左辺値(既知のシステム属性の場合はそれにあわせる)や右辺値(左辺値から推測できなかった場合、右辺値が数値や日付として解釈できる場合はそれを優先する)から属性の種類を推測して、

$condition->attributes[] = '@title STREQ foo';
$condition->attributes[] = '@mtime NUMLE 2006/6/6';

とかに展開するようにしてみたんだけど、なんかいまいちすっきりしなくて中断中。どうせなら、

$condition->attributes[] = '@title == foo';
$condition->attributes[] = '@mtime >= 2006/6/6';

にしちゃった方がいいかなー。最悪でもセットされたパラメータをそのままHyper Estraierに渡せるようにしておけば、悪影響は出ないかな?

このエントリーを含むはてなブックマークはてなブックマーク - Zendネームスペースの下に入れるのはやめた Share on Tumblr このエントリをつぶやくこのWebページのtweets
Filed under: 日記 No Comments