为什么map :: operator []设计缓慢?

Sam*_*Sam 3 c++ performance stl std libstdc++

问题:

Peope抱怨这个: 在STL地图中,使用map :: insert比[]更好吗?

访问时

std::map<Key, ExpensiveDefaultConstructorValue> data;
data[key1] // <-- Calls default constructor each time it is called, 
           // even when the element is there
Run Code Online (Sandbox Code Playgroud)

实现简单而优雅,但效率很低(从unordered_map中获取).

_Tp& operator[](const key_type& __key)
   { return _M_ht.find_or_insert(value_type(__key, _Tp())).second; }
Run Code Online (Sandbox Code Playgroud)

明显的解决方案

_Tp& operator[](const key_type& __key)
   { return _M_ht.find_or_insert_default(key_type(__key)).second; }
Run Code Online (Sandbox Code Playgroud)

哪里find_or_insert_default会打电话_Tp(),如果只需要(即元素不存在)

为什么不?

是否有一些其他问题可能是由于这种悲观的方法在建立一个新元素之前知道你需要它?

这是标准库,他们应该竭尽全力优化它.为什么不使用这种简单的方法?

Zet*_*eta 5

std::map至少从g ++ 4.5开始就没有这样的问题了:

// stripped comments and requirements
mapped_type&
operator[](const key_type& __k)
{    
    iterator __i = lower_bound(__k);

    if (__i == end() || key_comp()(__k, (*__i).first))
        __i = insert(__i, value_type(__k, mapped_type()));
    return (*__i).second;
}
Run Code Online (Sandbox Code Playgroud)

您发布的代码段不是来自std::map,而是来自hash_map,这是该库的GCC 扩展:

00052 /** @file backward/hash_map
00053  *  This file is a GNU extension to the Standard C++ Library (possibly
00054  *  containing extensions from the HP/SGI STL subset).
00055  */
Run Code Online (Sandbox Code Playgroud)

由于它是一个扩展,维护者没有义务遵循任何复杂性/性能规则(即使你提出的功能会更快).请注意,hash_map已被实现替换,std::unordered_map如果元素存在,则不使用构造函数.