2

問題を説明するための最小限のコードを提示します。

struct A {
  vector<string> v;
  // ... other data and methods
};
A obj;
ifstream file("some_file.txt");
char buffer[BIG_SIZE];
while( <big loop> ) {
  file.getline(buffer, BIG_SIZE-1);
  // process buffer; which may change its size
  obj.v.push_back(buffer);  // <------- can be optimized ??
}
...

ここで2 回 stringの作成が行われます。1 回目は実際のstringオブジェクトを作成し、2 回目はvector. デモ

push_back()操作は何百万回も発生し、私は何回も無駄な追加の割り当てを 1 回支払っています。

これを最適化する方法はありますか? 私はどんな適切な変更にもオープンです。push_back()(コード全体で何度も発生するため、これを時期尚早の最適化と分類しないでください)。

4

3 に答える 3

3

いくつかのことを試すことができます。1 つ目は、明らかにコンパイラで最適化を有効にすることです。 として宣言できる場合は、vector<const string>それが役立つ場合があります。

それ以外の場合は、次のようなものを試すことができます。

obj.v.resize(obj.v.size()+1);
obj.v.back().swap(string(buffer));
于 2011-09-28T04:58:43.527 に答える
3

さて、2 つの割り当てが得られますが、両方が文字列であるわけではありません: 1 つは文字列を作成し、もう 1 つはベクトル内のポインターを作成します (これはコンパイラーに依存することに注意してください: 一部のコンパイラー/設定は実際に2 つの文字列を作成しますが、ほとんどは作成しません)。デモのこのコードを見てください。

それを最適化する 1 つの方法は、テンプレート パラメーターとして文字列の代わりに char* を使用することです (ベクターを強制終了する前に手動で削除することを忘れないでください!)。このようにして、割り当ての 1 つ (最大) を取り除くことができます。または、独自の vector の実装を使用するだけです。これにより、メモリ割り当てのあらゆる側面を制御できるようになります。

于 2011-09-28T05:05:46.110 に答える
0

スタックにバッファを配置する代わりに、ヒープに配置します。次に、ポインターのベクトルを使用します。唯一

于 2011-09-28T05:10:39.363 に答える