【发布时间】:2020-10-30 21:59:27
【问题描述】:
我想有效地找到一个集合的索引。我正在使用 unordered_map 并像这样制作逆映射
std::unordered_map <int, int> myHash (size);
Int i = 0;
for (it = someSet.begin(); it != someSet.end(); it++)
{
myHash.insert({*it , i++});
}
它有效,但效率不高。我这样做了,所以只要我需要索引,我就可以访问它们 O(1)。性能分析显示这部分成为我代码的热点。
VTune 告诉我 new 运营商是我的热点。我猜 unordered_map 内部正在发生一些事情。
在我看来,这个案子应该得到有效处理。我还没有找到好的方法。有更好的解决方案吗?一个正确的构造函数?
也许我应该将更多信息传递给构造函数。我查看了初始化列表,但它并不是我想要的。
更新:让我添加更多信息。套装没那么重要;我将集合保存到一个数组中(排序)。稍后我需要找到唯一值的索引。我可以在登录中做到这一点,但速度不够快。这就是我决定使用哈希的原因。集合的大小(子矩阵的列)在此之后不会改变。
它来自稀疏矩阵计算,我需要在更大的矩阵中找到子矩阵的索引。因此,查找的大小和模式取决于输入矩阵。它适用于较小的问题。我可以使用查找表,但是当我计划并行执行时,每个线程的查找表可能很昂贵。我在创建时具有哈希的确切大小。我认为通过将它发送给构造函数它会停止重新分配。我真的不明白为什么要重新分配这么多。
【问题讨论】:
-
Int?你的意思是int? -
你要转换多少个元素?你在做多少次查找?创建查找表的费用可能超过您获得的任何节省,因此它可能是错误的优化。有一些阈值,元素数量 > N 和查找数量 > M 产生正面结果,但低于该阈值实际上是净负面结果。
-
为什么要一个 set 元素的索引?即使你拥有它,访问元素(使用
std::distance()也是 O(n)。 -
@ALX23z std::set 在调整大小时确实无效,它没有调整大小...
-
这个问题很可能是由于数组的大小。由于过大的碎片分配,使查找太大肯定会导致问题。考虑为您的项目解决算法问题。尝试以其他方式查找索引或使用
pmr分配unordered_map。如果您只是添加元素,也许您可以进行大量预订,然后将元素一个接一个地放置
标签: c++ performance set unordered-map