vector.reserve()の使い方

最近見た他所のチームのソース。DBに対してSQLのselect文で取れただけfor文を回しているのはいいとして、forループの内部で毎回reserve()を1個ずつ増やしては追加するということをやっていた。push_back()すればいいだけなのに、ちょっと違うんじゃないかなということで調べてみた。

vectorの要素数を増やすのはresize()です。reserve()というのは別物で、呼んでも要素数は変わりません。

じゃあ何をやってるのかというと…

vectorの要素数が増える時には、内部的にはこんな事が起きます。

1. 新しい領域を確保(new)する。
2. 古い領域から、今までの要素を新しい領域にコピーする。
3. 古い領域を捨てる(delete)。

これは結構重い処理なので、これをできるだけやらないために、vectorには「実際の要素数(size())より大き目の領域をとっておく」機能が有ります。これがreserve()です。

例えばreserve(1000);とすると、その後要素数が1000個を超えるまでは上の1〜3の処理をしなくて済むので、速くなります。

vector関数reserve()の用途 - C++ Builder / Turbo C++ 質問の木

まず前提として, vector は基本的にメモリの開放を行わないものと仮定することができる。これは,メモリの再確保(再配置)の発生頻度を出来るだけ減らすためだ。例として SGI の実装を参照してみると,「バッファのオーバーフローが発生する度に容量を2倍にする」というような記述は見られるものの,開放についてはまったく触れられていないことが分かる。

radiumsoftware.com

reserve はメモリを拡張する方向にしか働かないし, clear を発行したとしても,ほとんどの実装ではメモリを開放しないようだ。

radiumsoftware.com

ということは、僕が見たソースの場合、一度カーソルの最大フェッチ数だけreserve()しとけばよいのかな。