C++:value_type 与 make_pair,哪个映射插入更快?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4623610/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++: value_type versus make_pair, which is faster for map insert?
提问by Ashwin Nanjappa
typedef map<KeyType, ValType> KVMap;
KVMap kvmap;
kvmap.insert( KVMap::value_type( key, val ) );
kvmap.insert( make_pair( key, val ) );
Which of the above options to insert to a STL map is always faster? Why?
插入到 STL 映射的上述哪个选项总是更快?为什么?
Note: I am well aware that insert()
is faster than using []=
for adding (not updating) key-value pairs to a map. Please assume that my query is about adding, not updating. Hence I have restricted it to insert()
.
注意:我很清楚这insert()
比[]=
用于向地图添加(不更新)键值对要快。请假设我的查询是关于添加,而不是更新。因此,我将其限制为insert()
.
采纳答案by icecrime
Chances are that the first will be 'epsilon-faster', because of this (from 23.3.1 in the standard) :
有可能第一个将是'epsilon-faster',因此(从标准中的 23.3.1 开始):
typedef pair<const Key, T> value_type;
[...]
pair<iterator, bool> insert(const value_type& x);
In the first version, you directly construct the appropriate type expected by
std::map<K,V>::insert
In the second version, a conversion using
std::pair
template constructor is involved. Indeed,std::make_pair
will most likely deduce its template arguments toKeyType
andValType
, thus returning astd::pair<KeyType, ValType>
.This does not match the parameter type of
std::map<K,V>::insert
, which isstd::pair<const KeyType, ValType>
(the difference being theconst
-qualified first). Thestd::pair
conversion constructor will be used to create astd::pair<const K, V>
from thestd::pair<K, V>
.
在第一个版本中,您直接构造了预期的适当类型
std::map<K,V>::insert
在第二个版本中,
std::pair
涉及使用模板构造函数的转换。实际上,std::make_pair
很可能会将其模板参数推导出为KeyType
andValType
,从而返回 astd::pair<KeyType, ValType>
。这与 的参数类型不匹配
std::map<K,V>::insert
,即std::pair<const KeyType, ValType>
(区别在于const
- 限定在前)。该std::pair
转换构造函数将被用来建立一个std::pair<const K, V>
从std::pair<K, V>
。
To be fair, I don't believe you could even measure the difference (and I'm not even sure that popular compilers will actually generate a different code for these).
公平地说,我不相信你甚至可以衡量差异(我什至不确定流行的编译器实际上会为这些生成不同的代码)。
回答by templatetypedef
There actually is an argument to be made for value_type
over make_pair
. This is because, for various arcane reasons, make_pair
accepts its arguments by value. On the other hand, value_type
, an alias for std::pair<const Key, value>
, will have its constructor called with the arguments passed by const reference. There's a potential loss of efficiency from the pass-by-value in make_pair
versus pass-by-reference, which could in theory have a noticeable impact on your program.
实际上有一个争论要value_type
结束make_pair
。这是因为,出于各种神秘的原因,make_pair
按值接受其参数。另一方面,value_type
, 的别名std::pair<const Key, value>
, 将使用由 const 引用传递的参数调用其构造函数。make_pair
与通过引用传递值相比,传递值存在潜在的效率损失,理论上这可能会对您的程序产生显着影响。
Another issue to be worried about with make_pair
is that make_pair
will usually create a pair of type std::pair<Key, Value>
versus the std::pair<const Key, Value>
needed inside the map
. This means that there might be another unnecessary copy being made, this time of the pair
to get the conversion working correctly.
与担心的另一个问题make_pair
是,make_pair
通常会创建一个对类型std::pair<Key, Value>
相对于std::pair<const Key, Value>
需要内部map
。这意味着可能会制作另一个不必要的副本,这次是pair
为了使转换正常工作。
In short, using make_pair
might cause two completely unnecessary copies of the key and value to get made, while using the value_type
constructor has none.
简而言之,使用make_pair
可能会导致生成两个完全不必要的键和值副本,而使用value_type
构造函数则没有。
回答by Ise Wisteria
This is just a supplementation.
这只是一个补充。
insert( make_pair(...) )
calls copy constructor 4 times notionally because of the reason other
answerers mentioned.
insert( make_pair(...) )
由于其他回答者提到的原因,理论上调用了复制构造函数 4 次。
insert( value_type(...) )
calls copy constructor 2 times.
insert( value_type(...) )
调用复制构造函数 2 次。
operator[]
calls default constructor once and copy constructor 2 times
in a typical implementation.
default constructor is called inside operator[]
for
insert( value_type( ..., mapped_type() ) )
.
copy constructor is called once for copying insert()
's argument(pair
),
and once to copy-construct an internal node of the map.
operator[]
在典型的实现中调用一次默认构造函数并复制构造函数 2 次。在operator[]
for
内部调用默认构造函数insert( value_type( ..., mapped_type() ) )
。复制构造函数被调用一次以复制insert()
的参数(pair
),一次复制构造映射的内部节点。
So, if you use insert
with make_pair
,
it cannot be said that insert
is always faster than operator[]
even for adding.
Probably, it depends on the situation.
As you may know, in view of the above, emplace
was proposed for the new
standard.
所以,如果你使用insert
with make_pair
,不能说它insert
总是比operator[]
添加更快。也许,这取决于情况。如您所知,鉴于上述情况,emplace
提出了新标准。
回答by Karl Knechtel
They are fundamentally the same thing. KVMap::value_type
is a typedef for std::pair<KeyType, ValType>
, so that's just calling the constructor. std::make_pair
is a template function that simply calls the constructor (it exists because template types can be deduced for free functions, but not for constructors). Once all the unbelievably-standard optimizations are done, there is no reason for there to be any difference.
它们基本上是同一回事。KVMap::value_type
是一个 typedef for std::pair<KeyType, ValType>
,所以这只是调用构造函数。std::make_pair
是一个简单调用构造函数的模板函数(它存在是因为可以为自由函数推导出模板类型,但不能为构造函数推导出模板类型)。一旦完成了所有令人难以置信的标准优化,就没有理由存在任何差异。
I don't know how you're testing, but there are many, many ways to do that wrong.
我不知道你是如何测试的,但是有很多很多方法可以做到这一点。
As for insert()
vs. assigning via operator[]
, the latter has to do more work conceptually (when you add a new element this way, it first is supposed to default-construct an element, and then assign over top of it), but depending on the ValType
, it could conceivably be optimized into basically the same thing again.
至于insert()
与分配 via operator[]
,后者必须在概念上做更多的工作(当你以这种方式添加一个新元素时,它首先应该默认构造一个元素,然后在它上面分配),但取决于ValType
,可以想象,它可以再次优化为基本相同的东西。