2

私は自分のアプリケーションのプロファイルを作成するために非常に眠くなり、関数に費やされた時間の25%と23%がそれぞれnewとdeleteを実行していることを示しています。これがどこで起こっているのかわかりません。だから誰かが私のコードのどこでこれが起こっているのか教えてもらえますか?

inline FixParser(fixmessage& tokenMap, const std::string& str) {
  static seperator sep_delim("\x01");
  static seperator sep_equal("=");
  static std::string error("ERROR: ");
  static FixKey fix_Key;
  static tokenizer token_equal(error);
  static tokenizer token_delim(error);
  static tokenizer::iterator itr;
  token_delim.assign(str, sep_delim);
  int key;
  try {
    for(tokenizer::iterator it = token_delim.begin(); 
        it != token_delim.end(); ++it) {
      token_equal.assign(*it, sep_equal);
      itr = token_equal.begin();
      key = boost::lexical_cast<int>(*itr);
      if(fix_Key.keys.find(key) == fix_Key.keys.end()) continue;
      ++itr;
      const std::string& value(*itr);
      tokenMap.insert(std::pair<int, std::string>(key, value));
    }
  } catch(boost::bad_lexical_cast &) {
    std::cerr << error << str << std::endl;
    return;
  }
}

非常に眠い結果

staticそれらの使用は後で削除され、に配置されることをお許しstructください。

4

4 に答える 4

3

注:コピーされる文字列はたくさんあります。各文字列には、newメモリを取得しdeleteて解放するための呼び出しが発生します。

パフォーマンスが重要であり、そのコピーを保持できる場合は、str代わりにインデックスを使用することをお勧めします。つまり、トークンを本格的な文字列ではなく、インデックスのペア(begin、end)にすることです。これは明らかにエラーが発生しやすくなります。

また、tokenMapマップ内のエントリごとに1つのノードを割り当てます。エントリが多い場合は、ノードが多くなります(したがって、ノードnewを作成します)。代わりに使用して、提供dequeするものが本当に必要な場合を除いて、完了したらアイテムを並べ替えることができmapます(自動重複排除)。


Bikeshededバージョン、ほとんどの静的変数を削除(自分自身を助けることができませんでした):

inline FixParser(fixmessage& tokenMap, const std::string& str) {
  static seperator sep_delim("\x01");
  static seperator sep_equal("=");
  static FixKey const fix_Key;

  try {
    tokenizer token_delim(str, sep_delim);

    // avoid computing token_delim.end() at each iteration
    for(tokenizer::iterator it = token_delim.begin(), end = token_delim.end(); 
        it != end; ++it)
    {
      tokenizer token_equal(*it, sep_equal);

      tokenizer::iterator itr = token_equal.begin();
      int const key = boost::lexical_cast<int>(*itr);
      if(fix_Key.keys.find(key) == fix_Key.keys.end()) continue;

      ++itr;
      tokenMap.insert(std::make_pair(key, *itr));
    }
  } catch(boost::bad_lexical_cast &) {
    std::cerr << error << str << std::endl;
    return;
  }
}
于 2012-05-02T15:41:09.637 に答える
2

デバッグバージョンではなく、リリースビルドをテストしていることを確認してください。デバッグビルドはの異なるバージョンを使用newdelete、速度を犠牲にしてメモリリークを検出するのに役立ちます。また、デバッグビルドはあまり最適化されません(あるとしても)。

于 2012-05-02T17:45:24.963 に答える
0

見てみますboost::lexical_cast。最も単純な形式では、単にストリームを使用します。それはおそらく多くの割り当てを行います。

于 2012-05-02T15:40:48.690 に答える
0

静力学が問題である可能性があります。関数を何回呼び出していますFixParserか?

それを呼び出すたびにtoken_delim、オブジェクトには割り当てメソッドが呼び出されます。これらがベクトル割り当てのように実装されている場合、シーケンスを支えるメモリは破棄され、関数が呼び出されて新しいエントリを割り当てるtoken_equalたびに割り当てられます。FixParser

于 2012-05-02T16:09:53.127 に答える