iteratorは遅い?
前に、宴会だけのPHP勉強会で話した(す時間がほとんど無かった)SPLのiteratorについて、思ったより興味もってもらえたので、もちょっと調べてみた。
#というわけで、はてなダイアリーつかってみた。
$arr = array('val-00000', : 'val-49999'); $arrObj = new ArrayObject($arr); $iterator = $arrObj->getIterator();
// 配列版 foreach($arr as $key => $val) { $tmp = sprintf("'%s',\n", $val); } // パターン A. while ($iterator->valid()) { $tmp = sprintf("'%s',\n", $iterator->current()); $iterator->next(); } // パターン B. $offset = 0; while ($iterator->offsetExists($offset)) { $tmp = sprintf("'%s',\n", $iterator->offsetGet($offset++)); }
配列はともかく、パターンAより、オフセットをずらしているだけのパターンBの方が速いだろうとは思っていたけど、予想以上に大差が。
配列版 Offset 10000: [0.0699 sec.] -- [nivcsw 17] -- [VmSize: 29940 kB] Offset 20000: [0.1403 sec.] -- [nivcsw 27] -- [VmSize: 29940 kB] Offset 30000: [0.2104 sec.] -- [nivcsw 37] -- [VmSize: 29940 kB] Offset 40000: [0.2792 sec.] -- [nivcsw 49] -- [VmSize: 29940 kB] Offset 50000: [0.3491 sec.] -- [nivcsw 60] -- [VmSize: 29940 kB] パターンA Offset 10000: [ 3.9680 sec.] -- [nivcsw 118] -- [VmSize: 28404 kB] Offset 20000: [ 26.5991 sec.] -- [nivcsw 574] -- [VmSize: 28404 kB] Offset 30000: [ 64.3590 sec.] -- [nivcsw 1307] -- [VmSize: 28404 kB] Offset 40000: [117.0404 sec.] -- [nivcsw 2334] -- [VmSize: 28404 kB] Offset 50000: [184.6406 sec.] -- [nivcsw 3634] -- [VmSize: 28404 kB] ~~~~~~~~~~~~~ パターンB Offset 10000: [0.0884 sec.] -- [nivcsw 16] -- [VmSize: 28400 kB] Offset 20000: [0.1764 sec.] -- [nivcsw 28] -- [VmSize: 28400 kB] Offset 30000: [0.2633 sec.] -- [nivcsw 40] -- [VmSize: 28400 kB] Offset 40000: [0.3506 sec.] -- [nivcsw 51] -- [VmSize: 28400 kB] Offset 50000: [0.4390 sec.] -- [nivcsw 62] -- [VmSize: 28400 kB]
もともとSPLのiteraotrは、なんでもforeachで回しちゃえみたいなもの?なので、実際にforeachで回すときにどうなっているのか見ようと、役に立たないクラスを被せてみた。
$obj = new testIterator($arr);
foreach($obj as $val) {
$tmp = sprintf("'%s',\n", $val);
}
class testIterator extends ArrayObject
{
public function __constructor(array $arr)
{
parent::__constructor($arr);
}
}
はい、何もかも、ArrayObjectお任せなので、classに意味はありませんが。
で、結果は下記の通り。
Offset 10000: [ 4.1064 sec.] -- [nivcsw 97] -- [VmSize: 28400 kB] Offset 20000: [ 26.6693 sec.] -- [nivcsw 526] -- [VmSize: 28400 kB] Offset 30000: [ 64.3097 sec.] -- [nivcsw 1238] -- [VmSize: 28400 kB] Offset 40000: [116.5720 sec.] -- [nivcsw 2202] -- [VmSize: 28400 kB] Offset 50000: [183.6532 sec.] -- [nivcsw 3467] -- [VmSize: 28400 kB]
うーん、next()とcurrent()を使っているのかな。とりあえず、ぼーっとiteratorを使ってしまうのは怖そう。
こんなところで時間がつきたので、ArrayObjectの中身は別途。
不要とは思いつつ、勉強会LLでのPPT。。。を上げようと思ったら、ファイルアップロードがなかった。
勉強会資料と資料の追記を載せようと はてなダイアリーを書いてみたのに(汗
[後記]別場所におきました。勉強会LLでのPPT