追記履歴
- 2017/04/30
@faithandbrave@github さんからご指摘いただき「何故使うべきではないか?」のところに
synchronized_pool_resourceを使ったときの結果も記載しておきました。
boost::pool_objectよりも速かったですがシステムアロケータの解放よりは若干遅かったです。
(unsynchronized_pool_resourceも載せようとしましたがなぜかpool作成で不完全な型でエラーになったためやめました)
最初に
boostライブラリにはobject_poolというテンプレートが用意されています。
この記事は 絶対にobject_poolを使うべきではない 理由を書いていきます。
そもそもobject_poolとは?
すごく簡単に言うと、テンプレート引数で指定された型のメモリープールを作成、管理してくれるテンプレートです。
使用例コードです
boost::object_pool<int> pool;
int* p = pool.construct(10);
pool.destroy(p);
使い方も難しくはないし、便利そうです。
何故使うべきではないか?
一言で言うと destroy(オブジェクトの解放)が非常に遅いから です。
※synchronized_pool_resourceのサンプルも追記済みです。
なぜ遅いか?
どうやらオブジェクトのプールリストを単方向リストで管理しているらしく削除のたびにリストを検索して削除していく仕組みのようです。
このリストの検索が計算オーダーO(N)なのでオブジェクトが増えれば増えるほどこの検索時間がかかります。
もっと都合がわるいことに、オブジェクトをconstructした順番にdestroyを呼び出すと最悪ケースの処理時間になるようです。
例:a,b,cの順番でconstructしたものをa,b,cの順番でdestroyすると遅くなる
この問題は2009年12月12日に報告されて以来、メンテナンス者が不在のため放置され続けている問題です。
おそらく修正されない悲しい問題なので使わないほうが良さそうです
最後に
object_poolがよろしくないという原因で不具合の修正にご協力いただいた方々に深く感謝します。