再開発≠再実装

http://d.hatena.ne.jp/tt_clown/20091228/1261996214http://d.hatena.ne.jp/monjudoh/20091228/1262023451http://d.hatena.ne.jp/Isoparametric/20091230/1262134418の話。

態度表明。

先に明言しておくと、私は「再開発はするな。再実装は考えてからしろ」という意見だ。これだけだと是々非々=単なる日和見ともとれる無意味な意見になってしまうので、以下では再実装するべき条件について書く。

STLコンテナの現状を。

STLコンテナ共通の仕様では主要インターフェースが定義されている。STLではこのインターフェースを用いて検索やソートなどの基本アルゴリズムを利用する。この仕組みはC++ templateの基本思想に沿って作られており、オーバーヘッドを最小(大抵の場合は文字通り0)にすることができる。
STLコンテナ個別の仕様ではコンテナ全体のメモリ効率や主要インターフェースの速度効率まで定義されている。大抵の場合は用途にあったスペックのコンテナを選ぶ、要求水準が高ければ複数のコンテナ・複数のSTL実装を実ベンチマークで比較して選ぶ、というように開発を効率化することができる。
このような過程を経たC++コードは大抵の手書きCコードと同程度の性能を持つ。メモリアロケータのチューニングを行えばCコードを上回る性能に至ることもしばしばある。

目的と対応を考える。

学習目的
これは実装したコードが目的ではなく実装する行為が目的なので、再実装するのも再開発するのも自由だろう。
コードサイズ削減
大抵のSTLやtemplateはコードサイズの最小化を目的としていないため、単純にSTLを使うのでは失敗する。
追加機能
この場合に再開発するのは無駄だろう。Boostなどを参考にしつつ、STLコンテナを拡張したコンテナを開発するべきだ。
性能目的
STL範囲内でのチューニングで要求性能を満たせない場合もある。この場合の再実装のみが議論の対象になっていると思う。

要求性能を満たせないなら。

STLコンテナを適切に使っても要求性能を満たせない場合、次のような可能性を疑っておく必要がある。これらが原因ならば用途に特化したコンテナを用意してオーバーヘッドを削った程度では解決できないと思われる。遡って軌道修正するべきだろう。

  • そもそも要求水準が高すぎる。
  • 不適切なアルゴリズムを利用している。
  • 排他・同期に時間をとられている。

こういった問題がないことが明らかであってコンテナの性能を高めなければならない場合に初めて再実装を行う意味があると思う。その場合にもSTLコンテナの延長として開発するべきではないだろうか。STLコンテナのテストケースの大半を流用して品質を担保できるという点も魅力である。
例えば、stl::vectorのような擬似配列であれば、要素の追加・挿入の速度を犠牲にしても平均メモリ効率を向上したいことがある。このような要望は十分考えられるものだが、insert()時などに適宜reserve()を呼ぶようにstl::vectorを拡張すれば済むはずだ。また、STLコンテナのサブセットとして開発するのもよい。要素数を増減する必要は一切ないという条件ならばstl::vectorよりも高速な擬似配列を作るのも容易だろう。ただし、そういったコンテナは大抵Boostに存在していることを忘れてはならない。

〆。

STLなど、標準ライブラリ相当のものを再実装するのは確実に無駄だと思う。それとは逆に、"社内標準"など、ローカルライブラリは大抵ゴミなので標準ライブラリで置き換えることを考えるべきだと思う。