【问题标题】:Does std::map::find performance depend on the key size?std::map::find 性能是否取决于密钥大小?
【发布时间】:2014-05-01 16:08:15
【问题描述】:

假设我有以下map 定义:

std::map<string,Storage>

其中 keyStorage 类实例的字符串表示形式。
我的问题是,即使它声明 map::find complexity 大小是对数的string 大小对性能有影响吗?

我有这个map 的原因是为了能够快速访问Storage 类实例。但是,如果Storage 类的字符串表示很长怎么办?是否有一个最大字符串大小,如果超过了会导致使用 map 多余?

注意事项

我的直觉告诉我,如果 Storage 类的字符串表示很长,那么使用 operator== 比较类本身也会很昂贵。所以不管字符串有多长,我最好使用map

【问题讨论】:

  • map 中,与键相关的计算是比较和排序。如果您有具有相同长前缀的长字符串,这可能需要一些时间。但是,我高度怀疑这将是一个实际的性能瓶颈。别担心。基准、测量、仅在必要时进行优化。

标签: c++ map find time-complexity


【解决方案1】:

是的,地图必须对键进行小于比较。这是一个字典比较,并且是线性 WRT 字符串大小。

这不影响find方法的时间复杂度,它指的是需要比较的次数。影响常数因子。

这在您的应用程序中是否重要应根据经验确定。

【讨论】:

    【解决方案2】:

    std::map 对键类型使用字典顺序。这意味着地图上搜索操作的性能取决于地图中键的共享前缀和您要查找的键。如果您有许多键共享一个很长的前缀,并且您搜索具有该前缀的键,性能将会下降。

    例如,这是昂贵的:

    aaaaaa <millions of a's> aaaa
    aaaaaa <millions of a's> aaab
    aaaaaa <millions of a's> aaac
    

    这很便宜:

    aaaaaa <millions of a's> aaaa
    baaaaa <millions of a's> aaaa
    caaaaa <millions of a's> aaaa
    

    【讨论】:

    • 说您的“昂贵”示例适用于我的场景,我应该使用vector 而不是map 并使用operator== 比较实例吗?还是map 总是更有效?跨度>
    • @idanshmu 我不能说,你应该配置文件。也可以考虑std::unordered_map
    【解决方案3】:

    地图查找的“复杂性”以比较单位定义。所以“对数大小”意味着它将执行O(log(size())) 键比较。对于昂贵的键比较,这确实会影响实际性能。

    【讨论】:

    • 提问者感兴趣的不是性能如何与size() 相关,而是与密钥的大小相关。
    • @nightcracker 在我看来,OP 询问“复杂性”是否受密钥大小的影响。所以我说它会执行那么多 *key 比较,而不一定是那么多“恒定时间操作”。
    【解决方案4】:

    是的,比较两个字符串(具有长共享前缀)通常是 O(n) 复杂度。

    如果字符串不共享长前缀,则可能需要更少的时间。

    通常,较长的字符串需要较长的时间来比较。

    如果 key 是字符串,也许你应该考虑 unordered_map (hash_table)。

    【讨论】:

    • "一般来说,较长的字符串需要较长的时间来比较。"我会反对这一点。如果我们假设来自两个字符串的某些字符相同的概率是1/card(A),其中A 是字母表,那么简单的计算表明比较两个随机字符串需要O(1) 时间。无论如何,时间取决于字符串的分布。
    • @lisyarus 按字典顺序比较两个字符串是 O(N)。对此无能为力。
    • @juanchopanza:我说的是比较字符串负载的摊销时间。
    • @lisyarus 假设您对从平均大小为 N 的正态分布样本中随机抽取的字符串对进行 M 次比较。您是说这与使用平均大小的样本所花费的时间相同N*100?
    猜你喜欢
    • 1970-01-01
    • 2012-02-21
    • 1970-01-01
    • 2021-09-03
    • 1970-01-01
    • 2021-11-12
    • 2018-04-20
    • 2015-07-17
    • 1970-01-01
    相关资源
    最近更新 更多