c++ - 如何优化 std::map insert() 函数?

标签 c++ windows visual-studio dictionary std

解释我正在尝试完成的任务的最佳方法是使用此示例(使用 Visual Studio 2008 SP1 编译):

struct ELEMENT1{
    //Its members

    ELEMENT1()
    {
        //Constructor code
    }
    ~ELEMENT1()
    {
        //Destructor code
    }
};


std::map<std::wstring, ELEMENT1> map;

std::pair<std::map<std::wstring, ELEMENT1>::iterator, bool> resIns;
ELEMENT1 element;
std::wstring strKey;

for(size_t i = 0; i < numberRepetitions; i++)
{
    //Do processing
    //...

    //set 'strKey'

    //Insert new element into the map first
    resIns = map.insert(std::pair<std::wstring, ELEMENT1>(strKey, element));    //This line calls ELEMENT1 constructor & destructor twice

    //Then fill out the data
    fill_in_data(resIns.first->second);
}


BOOL fill_in_data(ELEMENT1& outInfo)
{
    //Fill in 'outInfo' -- MUST be in its own function
    //...
}

我的目标是优化这段代码,因此我做了以下事情:

  • ELEMENT1 元素 构造/销毁移到循环之外。

  • 我将 element 插入 map 中,然后尝试使用指向插入元素的指针来填充它,而不是构造新元素,然后填写它,然后将其复制到 map 中,然后销毁它。 (至少那是计划。)

但是当我将其编译为 Release 版本并检查汇编代码时,我可以看到带有 map.insert() 函数的 C++ 行调用 ELEMENT1 构造函数两次!然后两次它的析构函数。因此,以下机器代码仅适用于 map.insert() 行:

enter image description here

所以我显然在这里没有看到任何东西。

有人可以建议编译后的代码中发生了什么以及是否可以对其进行优化吗?

最佳答案

您有 2 个构造函数调用的原因是您传递给 insert 的内容与其所需的内容不匹配。 std::map::insert 采用 const value_type& 且 map 的 value_type

std::pair<const key_type, element_type>
          ^^^^^ this is important

因此,由于它们不匹配,因此您在使用时构造一个元素

std::pair<std::wstring, ELEMENT1>(strKey, element)

然后编译器调用复制构造函数将其转换为

std::pair<const std::wstring, ELEMENT1>

快速修复是将代码更改为

std::pair<const std::wstring, ELEMENT1>(strKey, element)

这给你留下了一个可以构建和销毁的临时对象。您也可以这样做zett42建议在 their answer完全避免创建临时文件。

关于c++ - 如何优化 std::map insert() 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44660832/

相关文章:

c++ - clang 交错源代码和程序集

c++ - x86 架构的内存排序限制

c++ - 处理大量规则(条件和约束)CEP 系统

c - 如何获取文件的 "valid data length"?

reactjs - 使用Typescript在Visual Studio 2017中 react Js

c# - 如何在 Expression Blend 2013 中获取 WPF 和 Windows Phone 模板?

c++ - 使用 pybind11,如何为 array_t 对象设置底层内存的所有权?

c++ - 将用户界面添加到图像查看器插件

python - 如何在 Windows 上捕获并打印来自 Internet 的数据包?

windows - Windows 和 Linux 中 "address in use"与 bind() 的区别 - errno=98