PHP でオブジェクトの集合を扱うなら Array より SplObjectStorage
2011-02-06 22:42:24
1 年半ほど前の記事ですが.
A Set of Objects in PHP: Arrays vs. SplObjectStorage
この記事を簡単にまとめると, 以下のような感じです.
- PHP でオブジェクトのユニークな集合を扱う方法には, 普通の Array を使う方法と, SplObjectStorage を使う方法がある.
- Array を使う場合は, spl_object_hash() でオブジェクトのハッシュを取り, それをキーに, オブジェクトを値にしたハッシュ変数として実装できる.
- SplObjectStorage は, PHP 5.2 以降に搭載された便利なコンテナクラスである.
- SplObjectStorage は, オブジェクトをユニークに格納することを保証する.
- SplObjectStorege は, C により実装されているので高速である. (ベンチマークでもそういう結果が出た)
- メモリの使用量においても, SplObjectStorage の方が少なくて済む.
というわけで, 手製のベンチマーキングフレームワークを使って, 自分でも計測してみました.
コンテナへの挿入
コンテナに 10,000 のユニークなオブジェクトを挿入する, というのを 100 回ずつ繰り返し, 計測してみます.
結果は以下のとおり.
array(): 2.8187828sec SplObjectStorage: 2.5617448sec
割と近い数値ですが, SplObjectStorage の方が速いようです.
オブジェクトの存在確認
10,000 個のオブジェクトを格納したコンテナを生成し, 新たに作ったオブジェクトの存在確認を 10,000 回行う.
つまり, 「存在しない値」なので, 全体に対してチェックが走ることになります.
とはいっても, 何らかのデータ構造を利用するはずなので 10,000 回のチェックが走るわけでは無いと思いますが.
そして実行結果.
array(): 0.0226268sec SplObjectStorage: 0.0183608sec
こちらも SplObjectStorage に軍配.
コンテナのイテレーション
コンテナに 10,000 個のオブジェクトを格納し, それらを foreach でイテレーションする, というのを 100 回繰り返す.
結果は以下のとおり.
array(): 0.6820778sec SplObjectStorage: 1.8508288sec
これについては Array が圧倒的な速さを見せました !
まとめ
- PHP でオブジェクトのユニークな集合を扱うコンテナは, SplObjectStorage が便利.
- SplObjectStorage は格納/存在確認ともに速い.
- ただし, イテレーションは Array の方が速い.
- 最終的にどっちを使うのが速いかはアプリケーションに依存する. (と思います)
個人的には, Observer Pattern の実装をするときに, Observer を格納するコンテナとしてよく利用します.
API もシンプルなので, まだ使ってない人も, 試してみてはいかがでしょう.