C++11 C++;地图::查找&;map::性能差异
我在给一些练习打分,在一个特定的程序中,虽然算法似乎正确,但速度太慢了(我的意思是太慢了太慢了)。程序使用C++11 C++;地图::查找&;map::性能差异,c++11,thread-safety,stdmap,C++11,Thread Safety,Stdmap,我在给一些练习打分,在一个特定的程序中,虽然算法似乎正确,但速度太慢了(我的意思是太慢了太慢了)。程序使用map::at(在C++11中引入)访问映射。只要将at替换为find(并修复语法),相同的程序就会非常快(与原始版本相比) 查看cplusplus.com,两种方法都声称具有相同的复杂性,我不明白为什么一种方法与另一种不同(除了API原因、不引发异常等) 然后我看到关于数据竞争的部分中的描述是不同的。但我并不完全理解其中的含义。我认为map::at是线程安全的(而map::find不是),
map::at
(在C++11中引入)访问映射。只要将at
替换为find
(并修复语法),相同的程序就会非常快(与原始版本相比)
查看cplusplus.com,两种方法都声称具有相同的复杂性,我不明白为什么一种方法与另一种不同(除了API原因、不引发异常等)
然后我看到关于数据竞争的部分中的描述是不同的。但我并不完全理解其中的含义。我认为map::at
是线程安全的(而map::find
不是),因此会导致一些运行时惩罚,这一假设正确吗
编辑
两者都在一个称为10.000.000次的循环中。没有优化标志。只需g++foo.cpp
。这是差异(arrayX是向量,m是映射)
second.find(array2.at(i));
second.size();
auto t = m.at(array1.at(i));
根据规则(同样适用于auto
说明符),在上述语句中,t
被推断为mapped_type
,从而触发对象复制
您需要将t
定义为auto&t
,以便将其推断为mapped\u类型&
相关对话:您观察到的性能差异可归因于对象复制
auto t = m.at(array1.at(i));
根据规则(同样适用于auto
说明符),在上述语句中,t
被推断为mapped_type
,从而触发对象复制
您需要将t
定义为auto&t
,以便将其推断为mapped\u类型&
相关对话:“除API原因外,不引发异常等”-这会影响性能。特别是如果它是算法的关键部分。线程安全版本也是一个触摸式的slower,在这两个版本中都没有出现任何异常。因此,没有“活动”异常处理发生,没有堆栈展开等。您对异常处理的理解有误。考虑<代码> STD::向量<代码> S>代码>运算符[] < /COD>和<代码> 函数。它们在速度上都是O(1)
。它们都允许您访问n
th元素。但如果您提供的索引不正确,运算符[]
行为未定义。也许它会给你一个垃圾参考<另一方面,在
处,每次调用它时,它都会执行check-simpleif
语句,以查看索引是否超出范围。如果是,则会引发异常。如果未引发异常且索引有效,则会“损失”一些时间来执行检查映射类型是什么?我很确定,对于代码中的auto t
,会推导出mapped\u type
(而不是参考),这会导致mapped\u type
副本。试试auto&t
。哇!这就是罪魁祸首。将auto-t
更改为auto&t
,并保持map::at
运行速度非常快!“除API原因外,不引发异常等”-这会影响性能。特别是如果它是算法的关键部分。线程安全版本也是一个触摸式的slower,在这两个版本中都没有出现任何异常。因此,没有“活动”异常处理发生,没有堆栈展开等。您对异常处理的理解有误。考虑<代码> STD::向量<代码> S>代码>运算符[] < /COD>和<代码> 函数。它们在速度上都是O(1)
。它们都允许您访问n
th元素。但如果您提供的索引不正确,运算符[]
行为未定义。也许它会给你一个垃圾参考<另一方面,在处,每次调用它时,它都会执行check-simpleif
语句,以查看索引是否超出范围。如果是,则会引发异常。如果未引发异常且索引有效,则会“损失”一些时间来执行检查映射类型是什么?我很确定,对于代码中的auto t
,会推导出mapped\u type
(而不是参考),这会导致mapped\u type
副本。试试auto&t
。哇!这就是罪魁祸首。将auto-t
更改为auto&t
,并保持map::at
运行速度非常快!我的错。我认为