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-simple
if
语句,以查看索引是否超出范围。如果是,则会引发异常。如果未引发异常且索引有效,则会“损失”一些时间来执行检查映射类型是什么?我很确定,对于代码中的
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-simple
if
语句,以查看索引是否超出范围。如果是,则会引发异常。如果未引发异常且索引有效,则会“损失”一些时间来执行检查映射类型是什么?我很确定,对于代码中的
auto t
,会推导出
mapped\u type
(而不是参考),这会导致
mapped\u type
副本。试试
auto&t
。哇!这就是罪魁祸首。将
auto-t
更改为
auto&t
,并保持
map::at
运行速度非常快!我的错。我认为 Audio/Cord>会更复杂,并且会密切关注确切的方法签名(包括引用)。C++页面绝对不是一个简单的(或令人愉快的)阅读!乔治·卡斯特里尼斯,但那样的话就没有那么灵活了。默认情况下,它总是生成一个非常量非引用副本,您可以轻松覆盖这两个功能。如果规则跟踪您调用的函数的类型,那么您必须始终查看该函数,以确定是否需要添加重写以使其成为非常量或副本,而事实上,该语言并不容易提供这两种功能(除非您通过类型特征转换器,这不太好)。好的,在一些情况下这是胡说八道,就像函数引用仍然是引用一样。我的错。我认为 Audio/Cord>会更复杂,并且会密切关注确切的方法签名(包括引用)。C++页面绝对不是一个简单的(或令人愉快的)阅读!乔治·卡斯特里尼斯,但那样的话就没有那么灵活了。默认情况下,它是alwa