为什么 map::operator[] 在设计上很慢
Why is map::operator[] slow by design?
问题:
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
实现简单而优雅,但完全效率低下(好吧,取自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()
(即元素不存在)
为什么不呢?
在知道您需要新元素之前构建新元素时,这种悲观的方法是否可能导致其他问题?
这是标准库,他们应该竭尽全力优化它。为什么不使用这种简单的方法?
至少
从 g++ 4.5 开始,std::map
就没有这样的问题了:
// 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 扩展:
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
的实现所取代,如果元素存在,则不使用构造函数。
相关文章:
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 使用一个考虑到std::map中键值的滚动或换行的键
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 允许从 std::map 的密钥窃取资源?
- 为什么 std::optional::operator=(U&&) 要求你是非标量类型?
- 'operator='已弃用:改用 QDir::setPath()
- 使用 operator[] 访问私有 std::map of unique_ptr
- 当 map 是一个整数数组并且由 operator[] 创建时,它是否初始化其映射类型
- 错误:与'operator='不匹配(操作数类型为"std::map<int、double>::iterator
- 为什么 vector::operator[] 的实现方式与 map::operator[] 不同?
- 为什么 map::operator[] 在设计上很慢
- 填充 std::map 时"C2593: operator = is ambiguous"
- Netbeans在使用c++std::map::operator[]时遇到一些问题
- std::map::operator[]违规访问windows上的内存
- 为什么C++ std::map::operator[] 不使用就地新?
- 错误:在map c++中没有匹配operator=
- 如何在初始化列表中使用std::map::operator=
- c++ STL map::operator[]在被删除的项上执行
- 可以依赖std::map::operator[]来触摸吗?