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::distanceequal_range 花费更多时间。 我天真地假设在进行 equal_range 时,距离是自动计算的。事实上,这是两个独立的计算。

有没有不同的方法来获取equal_range的元素总数?

【问题讨论】:

你需要范围和计数吗? 您的容器操作的内在复杂性(想想“Big-O 表示法”)是什么?也许,multimap 不是正确的工具? std::multimap::count,但它和你在这里写的一样复杂。 我需要计算以从 vector::push_back 中的循环中节省时间。 所以您要做的就是保留正确的尺寸?在推回中,无论如何它都会访问范围内的每个节点,所以我认为你无法赢得这个,除非你可以将矢量保留大小估计为地图大小()的 1/2? 【参考方案1】:

std::multimap::equal_rangeO(log <size of the container>)std::distanceO(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 地图中被击中?

MYSQL:用union查询2个表很慢,如何改进?

为啥 std::distance() for std:list<int>::iterator 在 last 在 first 之前不返回负数?

在std :: list中,std :: distance(it.begin(),std :: prev(it.end())是否等于list.size()? [重复]

`std::partition()` 的时间复杂度

查询很慢,我可以做些啥来改进?