std::distance 很慢,如何改进? [关闭]
Posted
技术标签:
【中文标题】std::distance 很慢,如何改进? [关闭]【英文标题】:std::distance is slow and how to improve it? [closed] 【发布时间】:2019-07-29 16:52:01 【问题描述】:std::distance
似乎很慢。我有一个大的多图并尝试使用equal_range
来查找具有公共键的元素:
auto range = in_map.equal_range(neuron_with_spikes[i]);
int count = std::distance(range.first, range.second);
std::distance
比 equal_range
花费更多时间。
我天真地假设在进行 equal_range 时,距离是自动计算的。事实上,这是两个独立的计算。
有没有不同的方法来获取equal_range
的元素总数?
【问题讨论】:
你需要范围和计数吗? 您的容器操作的内在复杂性(想想“Big-O 表示法”)是什么?也许,multimap
不是正确的工具?
有std::multimap::count
,但它和你在这里写的一样复杂。
我需要计算以从 vector::push_back 中的循环中节省时间。
所以您要做的就是保留正确的尺寸?在推回中,无论如何它都会访问范围内的每个节点,所以我认为你无法赢得这个,除非你可以将矢量保留大小估计为地图大小()的 1/2?
【参考方案1】:
std::multimap::equal_range
是 O(log <size of the container>)
和 std::distance
是 O(linear <size of the range>)
和 std::multimap::count
是这两者的总和。
这是完全合理的,因为地图已排序,并且您需要访问范围内的每个元素来计算它们 - 所以除非您可以在解决方案中摆脱一些这个 - 看起来像您尝试的正常行为做。
【讨论】:
【参考方案2】:没有;可以实现一个标准映射类型构造,其中计算迭代器之间的距离为 O(lg n),但标准映射不实现它。而且改装它并不容易;编写自己的容器可能同样简单。
在这样一个修改后的映射中,平衡二叉树跟踪总节点数;这为树突变和内存使用增加了一个恒定的开销因子,但在 O 表示法中没有。
最简单的方法,因为您只需要计数而不需要距离,可能会将您的多图替换为从键到元素向量的映射;并手动管理元素的向量。距离为 O(n),但计数变为 O(lg n)。
【讨论】:
我的多图已排序,即所有相同的键值都彼此相邻。可以只获取范围的第一个索引和最后一个索引号来加快速度吗? @David 在标准映射或多映射中没有 O(n) 时间的从迭代器到索引号的方法。因此,我回答的第一个词。第二段描绘了一个类似 std 映射/多映射的容器,该容器具有在 log n 时间内获取索引的属性;这不是 std map 或 multimap 所做的。我知道你不能使用 std map 容器来做到这一点,因为我一直想要它并反复尝试。第三段详细介绍了一种解决方法,将 multimap 替换为 std 映射到向量(甚至是 std 映射到 std 集或几乎任何具有 O(1) 计数的东西)。 第三个选项听起来更直接。谢谢以上是关于std::distance 很慢,如何改进? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
为啥 std::distance 在 stl 地图中被击中?
为啥 std::distance() for std:list<int>::iterator 在 last 在 first 之前不返回负数?
在std :: list中,std :: distance(it.begin(),std :: prev(it.end())是否等于list.size()? [重复]