unordered_map:为什么范围操作效率低下,情况就是这样
unordered_map : why range operation are inefficient, and this is case?
我得到了这个关于在C++中实现通用记忆的例子。但是,正如有人在此评论中注意到的那样,原始代码进行了 2 次查找,而下面的代码只进行了一次查找。
template <typename ReturnType, typename... Args>
std::function<ReturnType (Args...)> memoize(std::function<ReturnType (Args...)> func)
{
std::map<std::tuple<Args...>, ReturnType> cache;
return ([=](Args... args) mutable {
std::tuple<Args...> t(args...);
auto range = cache.equal_range(t);
if (range.first != range.second) return (*range.first).second;
return (*cache.insert(range.first, func(args...))).second;
});
}
有人注意到使用unordered_map可能会有更好的性能。但我读过:
对于通过子集进行范围迭代,它们通常效率较低 他们的元素。我不明白为什么范围操作较少 高效,如果上述情况是这些情况之一(因为我们使用 范围(?
正如有人在此评论中注意到的那样,原始代码进行了 2 次查找,而下面的代码只进行了一次查找
好的,因此您尝试使用提示insert
来避免对插入点进行冗余对数复杂性搜索。您仍然有与另一个问题相同的错误,您的代码可能如下所示:
cache.insert(range.first, std::make_pair(t, func(args...)));
// ^hint ^value_type
(这是链接文档中的重载 #4(。
你可以完全不用第一次查找:如果键存在,insert
只是将迭代器返回到现有元素,因此您可以使用乐观插入来编写它 - 这是否更好取决于默认构造的成本,然后分配您的 ReturnType:
auto result = cache.insert(make_pair(t, ReturnType{}));
if (result.second) {
// insertion succeeded so the value wasn't cached already
result.first->second = func(args...);
}
return result.first->second;
。使用unordered_map可能会有更好的性能...
std::map
查找/插入具有对数复杂度的比例,以及具有恒定复杂度的std::unordered_map
比例。哪个实际上更好取决于您有多少条目,以及其他因素,您需要分析以确定。
。[unordered_map] 对于范围迭代的效率较低......
好吧,如果您避免equal_range
,则根本不需要范围迭代.
查看您实际使用的操作,并了解哪种数据结构是自然适合的。对于简单的查找和插入,这是您在这里真正需要的,unordered_map
可能没问题。 std::map
如果你关心键的相对顺序会更好,而你不关心。
这两种结构对键也有不同的要求:map
需要一个排序(operator<
或自定义比较器(,而unordered_map
需要一个定义良好的哈希函数和operator==
或自定义谓词。
首先,我不确定std::hash
是否支持std::tuple
,因此您可能需要提供自定义哈希器才能使用unordered_map
。
- 在没有太多条件句的情况下,我如何避免被零除
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 函数中堆分配的效果与缺少堆分配的情况
- 在未初始化映射的情况下,将值插入到映射的映射中
- 用MacOS Mojave编译C++:致命错误:mpi.h:没有这样的文件或目录
- 是默认情况下分配给char数组常量的值
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 如何在不产生任何垃圾的情况下获得C中的像素
- 在已经使用Git的情况下减少编译时间
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 如何在没有信号的情况下从C++执行QML插槽
- 如何在不知道向量大小的情况下输入向量内部的向量?
- 函数如何在不这样做的情况下在新线程上运行"as if"?
- 如何在没有网络的情况下控制NodeMCU,但使用像Qt这样的GUI(通过wifi)?
- unordered_map:为什么范围操作效率低下,情况就是这样
- 如何在linux中使用c或c++在不使用system()或exec()函数的情况下调用像pwd或ls-l这样的系统函数
- 在一个结构向量中,我应该在结构中使用char[]而不是std::string,这样它们就是POD
- c++如何初始化对象?下面的情况是这样做两次吗
- 如何在没有逻辑运算符的情况下制作这样的程序?(和和或和)
- 如何在没有像print(f)这样的标准C函数的情况下将char转换为八进制格式