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

时间:2013-10-26 07:29:54

标签: c++ performance stl std libstdc++

问题:

Peope抱怨这个: In STL maps, is it better to use map::insert than []?

访问

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

实现简单而优雅,但效率非常低(从unordered_map中获取)。

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

明显的解决方案

_Tp& operator[](const key_type& __key)
   { return _M_ht.find_or_insert_default(key_type(__key)).second; }

find_or_insert_default仅在需要时才会调用_Tp()(即该元素不存在)

为什么不呢?

在知道你需要它之​​前构建一个新元素的悲观方法可能会导致其他问题吗?

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

1 个答案:

答案 0 :(得分: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;
}

您发布的代码段不是来自std::map,而是来自hash_map,这是GCC extension到图书馆:

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  */

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