配列要素の OR, AND をちょっとBenchmark取ってみた。
YakiBikiでは、特に検索処理において、ArrayのAND/OR演算を行います。自分では結構重い処理になると踏んでます。
で、実際どんなものか試してみました。
====
YakiBikiでは、AND, ORを(単純化すると)次のように実装してます。
OR演算: function array_or($arr1, $arr2) { return array_unique(array_merge($arr1, $arr2)); } AND演算: function array_and($arr1, $arr2) { return array_intersect($arr1, $arr2); }
で、実際に試したスクリプト:
<?php // AND演算 require_once('Benchmark/Timer.php'); $sz = 10000; $arr1 = array(); $arr2 = array(); $arr3 = array(); $arr4 = array(); for ($i = 0; $i < $sz; $i++) { $arr1[] = mt_rand(1, $sz); $arr2[] = mt_rand(1, $sz); $arr3[] = mt_rand(1, $sz); $arr4[] = mt_rand(1, $sz); } $t1 =& new Benchmark_Timer(); $t1->start(); $arr = array_intersect($arr1, $arr2); $t1->setMarker('m1'); $arr = array_intersect($arr1, $arr2, $arr3); $t1->setMarker('m2'); $arr = array_intersect($arr1, $arr2, $arr3, $arr4); $t1->stop(); $t1->display();
<?php // OR演算 require_once('Benchmark/Timer.php'); $sz = 10000; $arr1 = array(); $arr2 = array(); $arr3 = array(); $arr4 = array(); for ($i = 0; $i < $sz; $i++) { $arr1[] = mt_rand(1, $sz); $arr2[] = mt_rand(1, $sz); $arr3[] = mt_rand(1, $sz); $arr4[] = mt_rand(1, $sz); } $t1 =& new Benchmark_Timer(); $t1->start(); $arr = array_unique(array_merge($arr1, $arr2)); $t1->setMarker('m1'); $arr = array_unique(array_merge($arr1, $arr2, $arr3)); $t1->setMarker('m2'); $arr = array_unique(array_merge($arr1, $arr2, $arr3, $arr4)); $t1->stop(); $t1->display();
で、結果は眠いし面倒くさいので書きませんがPen4/2.8GHz/HTマシン上で、データ数が1000の場合はANDもORも、一気に処理する配列の数にほぼ線形に増加しましたが、1000の場合は10ms台で推移していきました。0.02sec - 0.04secですか。
数が10000になり1桁増えると、300msから始まり、500-600ms, 4つ一気だと1sec程度になりました。
結論としては、実際これがYakiBiki内で適用されるのってyb_tx_Search内の限られた箇所なんですよね。ですのでほんと、検索したときとか、あるいはrecentやlsプラグインを使っていた時くらいしか発動しないし、10000という一応当初レベルではほぼmax近い件数においても1sec程度に抑えられているので、これはこれで良いのかもと思っています。
それよりもidx系のファイル読み込みのオーバーヘッドとか、Cache_Lite使っているとはいえ実際どれくらい軽減できているのか。ひょっとして、粒度が細かすぎてファイル読み込みのオーバーヘッドが大きいのではないか、とか、いろいろその他の部分がきになる次第なのです。
いずれxdebugで少し詳しくprofilingするひつようがありそうです・・・。
ねむねむ。