【C++】vectorのメモリを事前確保するreserve()の使い方(パフォーマンス改善)

目次

はじめに

C++の std::vector は、要素を追加 (push_back) していくと、内部のメモリ領域(キャパシティ)が足りなくなった時点で、より大きな新しいメモリ領域を確保し、そこに全要素をコピーするという「メモリの再確保」を自動で行います。

この再確保は便利な反面、大量の要素を追加するループの中などで頻繁に発生すると、コピーのコストが積み重なり、パフォーマンスの低下を招きます。

もし、プログラムの実行前に「最終的に、少なくともこれくらいの要素数が必要になる」ということが分かっている場合、.reserve() メソッドを使って、あらかじめ十分なメモリ領域を確保しておくことができます。これにより、ループ中のメモリ再確保を未然に防ぎ、処理を大幅に高速化することが可能です。


reserve() を使ったサンプルコード

このコードは、.reserve() を使って事前にメモリを確保した場合と、使わなかった場合の capacity() の変化を比較します。

完成コード

#include <iostream>
#include <vector>

using namespace std;

int main() {
    // --- reserve() を使う場合 ---
    cout << "--- reserve() を使う場合 ---" << endl;
    vector<int> vec_with_reserve;
    
    // 1. 少なくとも1000個の要素が入るメモリを事前に確保
    vec_with_reserve.reserve(1000);
    
    cout << "確保後の capacity: " << vec_with_reserve.capacity() << endl;
    cout << "現在の要素数 (size): " << vec_with_reserve.size() << endl;

    // 1000個の要素を追加しても、メモリ再確保は発生しない
    for (int i = 0; i < 1000; ++i) {
        vec_with_reserve.push_back(i);
    }
    cout << "1000個追加後の capacity: " << vec_with_reserve.capacity() << endl;
    cout << "1000個追加後の size: " << vec_with_reserve.size() << endl;

    cout << "\n--- reserve() を使わない場合 ---" << endl;
    // --- reserve() を使わない場合 ---
    vector<int> vec_without_reserve;
    cout << "初期 capacity: " << vec_without_reserve.capacity() << endl;
    // 1000個の要素を追加する過程で、複数回のメモリ再確保が発生する
    for (int i = 0; i < 1000; ++i) {
        vec_without_reserve.push_back(i);
    }
    cout << "1000個追加後の capacity: " << vec_without_reserve.capacity() << endl;
    
    return 0;
}

コードの解説

vec_with_reserve.reserve(1000);

これが、メモリを事前確保する核心部分です。

  • .reserve(n): vectorのキャパシティ(.capacity()が返す値)が、少なくとも n 以上になるようにメモリを確保します。
  • もし、呼び出し時点のキャパシティが既に n 以上であれば、何も起こりません。
  • reserve() を呼び出しても、vector要素数 (.size()) は一切変わりません。ただ、将来の要素追加に備えて、内部のメモリ領域だけを拡張します。

パフォーマンスへの影響

reserve() を使わなかった vec_without_reserve の場合、1000回の push_back の間に、capacity0 -> 1 -> 2 -> 4 -> 8 -> ... のように、何度も拡張(再確保とコピー)されていきます。

一方、vec_with_reserve では、最初に 1000 以上のキャパシティを確保しているため、ループの中では一度も再確保が発生せず、単純な要素の追加だけが実行されます。要素数が非常に多い場合、この差はプログラム全体の実行時間に大きな影響を与えます。


まとめ

今回は、C++の vector(および string)のパフォーマンスを向上させる .reserve() メソッドについて解説しました。

  • .reserve(n) を使うと、少なくとも nの要素を格納できるメモリを事前に一括で確保できる。
  • これにより、ループ処理などでの断続的なメモリ再確保を防ぎ、処理を高速化できる。
  • .reserve() は要素数 (.size()) を変更するものではない。

プログラムのロジック上、最終的な要素数がある程度予測できる場合には、reserve() を積極的に活用することで、より効率的なコードを書くことができます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次