C++ 隐式new和delete运算符终止性能

C++ 隐式new和delete运算符终止性能,c++,optimization,new-operator,profiler,delete-operator,C++,Optimization,New Operator,Profiler,Delete Operator,我正在运行一个非常困倦的程序来分析我的应用程序,它告诉我25%和23%的时间花在我的函数上,分别是做new和delete。我不明白这是在哪里发生的。有人能告诉我这在我的代码中发生在哪里吗 inline FixParser(fixmessage& tokenMap, const std::string& str) { static seperator sep_delim("\x01"); static seperator sep_equal("="); static s

我正在运行一个非常困倦的程序来分析我的应用程序,它告诉我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;
  }
}
inlinefixparser(fixmessage&tokenMap,const std::string&str){
静态分离器sep_delim(“\x01”);
静态分离器sep_等于(“=”);
静态标准::字符串错误(“错误:”);
静态固定键固定键;
静态标记器标记_相等(错误);
静态标记器标记(错误);
静态标记器::迭代器itr;
令牌分配(str,sep-delim);
int键;
试一试{
for(tokenizer::iterator it=token_delim.begin();
it!=令牌_delim.end();++it){
标记等于赋值(*它,sep等于);
itr=令牌_等于.begin();
key=boost::词法转换(*itr);
如果(fix_Key.keys.find(Key)=fix_Key.keys.end())继续;
++itr;
常量标准::字符串和值(*itr);
insert(std::pair(key,value));
}
}捕获(boost::错误的\u词法\u cast&){

std::cerr我要看一下
boost::lexical_cast
。在最简单的形式中,它只是使用流。它可能会进行大量分配。

注意:有很多字符串被复制。每个字符串都会调用
new
来获取内存,然后调用
delete
来释放内存

如果性能很高,并且您能够保留
str
的副本,那么您可能需要使用索引。也就是说,将标记设置为索引对(开始、结束),而不是完整的字符串。这显然更容易出错

另外,
tokenMap
为映射中的每个条目分配一个节点,如果您有很多条目,那么就会有很多节点(因此
new
来创建它们)。您可能希望改用
deque
,并在完成后对项目进行排序,除非您确实需要
map
提供的功能(自动重复数据消除)


bikesheed版本,删除了大多数静态变量(无法帮助自己):

inlinefixparser(fixmessage&tokenMap,const std::string&str){
静态分离器sep_delim(“\x01”);
静态分离器sep_等于(“=”);
静态固定键常量固定键;
试一试{
代币人代币(str、sep);
//避免在每次迭代时计算token_delim.end()
for(tokenizer::iterator it=token_delim.begin(),end=token_delim.end();
它!=结束;++它)
{
记号赋予器记号相等(*it,sep_相等);
标记器::迭代器itr=token_equal.begin();
int const key=boost::词法转换(*itr);
如果(fix_Key.keys.find(Key)=fix_Key.keys.end())继续;
++itr;
insert(std::make_pair(key,*itr));
}
}捕获(boost::错误的\u词法\u cast&){

std::cerr静态可能是问题所在。您调用函数
FixParser
的次数是多少


每次调用
token_delim
token_equal
对象时,都会调用分配方法,如果这些方法像向量分配一样实现,则支持序列的内存将被销毁,然后在每次调用
FixParser
函数分配新条目时进行分配。

确保u正在测试发布版本,而不是调试版本。调试版本使用不同版本的
new
delete
,这有助于以牺牲速度为代价检测内存泄漏,调试版本没有进行太多优化(如果有的话).

我看不到图像,我打赌你们也看不到。真的,伙计们,只要在新选项卡上打开图像。或者右键单击>“查看图像”或者你的浏览器给你的任何东西。@Alex和Bitmap,在一个新选项卡中打开图像,并将其放大到100%,它非常清晰。你看到的是StackOverflow嵌入图像的方式。你在发行版上运行这个,对吗?不是调试吗?@ahenderson是的,在调试
新建
删除
中,由于调试速度慢得多r希望确保您没有内存泄漏。我认为情况并非如此。我尝试用静态值替换
key=boost::lexical_cast(*itr);
,但没有任何帮助。否:屏幕截图按包容性性能排序,并且
boost::lexical_cast
不会出现(在标记器出现的地方,很多)同时,由于OP使用的是Boost 1.47,他应该有一个优化版本。
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;
  }
}