C++ std::map::find性能是否取决于密钥大小?
假设我有以下C++ std::map::find性能是否取决于密钥大小?,c++,map,find,time-complexity,C++,Map,Find,Time Complexity,假设我有以下map定义: std::map<string,Storage> std::map 其中,键是存储类实例的字符串表示形式。 我的问题是,尽管它指出了复杂性 大小是对数的,字符串大小对性能有影响吗 我之所以有这个映射,是为了能够快速访问存储类实例。但是,如果存储类的字符串表示非常长,该怎么办?是否存在一个最大字符串大小,如果超过该最大字符串大小,将导致使用map冗余 笔记 我的直觉告诉我,如果存储类的字符串表示非常长,那么使用操作符==比较类本身也会很昂贵。因此,无论字符
map
定义:
std::map<string,Storage>
std::map
其中,键是存储
类实例的字符串表示形式。我的问题是,尽管它指出了复杂性 大小是对数的,
字符串
大小对性能有影响吗
我之所以有这个映射
,是为了能够快速访问存储
类实例。但是,如果存储
类的字符串表示非常长,该怎么办?是否存在一个最大字符串大小,如果超过该最大字符串大小,将导致使用map
冗余
笔记
我的直觉告诉我,如果
存储
类的字符串表示非常长,那么使用操作符==
比较类本身也会很昂贵。因此,无论字符串有多长,我最好使用map
是的,map必须执行少于键的比较。这是一个词典比较,与字符串大小成线性关系
这不会影响find
方法的时间复杂度,该方法指的是所需的比较次数。它影响常数因子
这在应用程序中是否重要,应该根据经验来确定。
std::map
对键类型使用字典顺序。这意味着地图上搜索操作的性能取决于地图中键的共享前缀和您要查找的键。如果有许多密钥共享一个很长的前缀,并且搜索具有该前缀的密钥,则性能将下降
例如,这很昂贵:
aaaaaa <millions of a's> aaaa
aaaaaa <millions of a's> aaab
aaaaaa <millions of a's> aaac
aaaaaaab
AAAAA aaaa
AAAAA aaaa
地图查找的“复杂性”是以比较为单位定义的。所以“大小对数”意味着它将执行O(log(size())
键比较。对于代价高昂的键比较,这确实会影响实际性能。是的,比较两个字符串(具有长共享前缀)通常是O(n)复杂度
如果字符串不共享长前缀,则可能需要较少的时间
通常,比较较长的字符串需要较长的时间
也许你应该考虑unGordEnmap(HasHiTable),如果KEY是一个字符串。
在<代码> MAP中,与密钥相关的计算是比较和排序。如果您有具有相同长前缀的长字符串,则可能需要一些时间。但是,我非常怀疑这是否会成为实际的性能瓶颈。别担心。基准测试、测量,仅在必要时进行优化。询问者感兴趣的不是性能如何与size()
相关,而是与键的大小相关。@nightcracker在我看来,OP是询问“复杂性”是否受键的大小影响。所以我说它会执行很多*关键比较,“不一定会执行很多”恒定时间操作“。比如说你的“昂贵的”示例适用于我的场景,我应该使用vector
而不是map
并使用操作符==
比较实例吗?或者map
将永远更有效?@idanshmu我不能说,你应该配置文件。“一般来说,较长的字符串需要更长的时间来进行比较。”如果我们假设两个字符串中的某些字符相同的概率为1/card(A)
,其中A
是字母表,那么简单的计算表明比较两个随机字符串需要O(1)
时间。无论如何,时间取决于字符串的分布。@lisyarus按字典法比较两个字符串是O(N)。对此我们无能为力。@juanchopanza:我说的是比较字符串负载的摊销时间。@lisyarus说你对从平均大小为N的正态分布样本中随机抽取的字符串对进行了m次比较。你是说这与平均大小为N*100的样本进行比较所需的时间相同吗?
aaaaaa <millions of a's> aaaa
baaaaa <millions of a's> aaaa
caaaaa <millions of a's> aaaa