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()しとけばよいのかな。