C++ unordered_map operator[] vs unordered_map.find() 性能

Yas*_*wal 5 c++ unordered-map hashmap time-complexity

我正在解决interviewbit.com 上的一个竞争性编程问题,我基本上使用了 unordered_map 来跟踪访问过的数字。当我使用operator[]时,我的代码无法及时执行,但是当我使用find时它通过了所有测试。两者应该具有相同的时间复杂度。

我尝试使用 clock() 对这两个代码进行计时,方法是将它们运行 10 次并平均运行时间,它们都或多或少地给出了相同的时间。我用的是g++ 7.4.0,而网站提供的环境是g++ 4.8.4。这可能是造成这种情况的原因。

int Solution::solve(vector<int> &A) {
    unordered_map<long long, int> hashmap;
    for(auto a : A)
        hashmap[a] = 1;
    int res = 0;
    for(int i = 0; i < A.size(); ++i){
        for(int j = i + 1; j < A.size(); ++j){
          // if(hashmap.find((long long)A[i] + A[j]) != hashmap.end())
            if(hashmap[(long long)A[i] + A[j]] == 1)
                ++res;
        }
    }
    return res;
}
Run Code Online (Sandbox Code Playgroud)

问题是在数组中找到总和也存在于数组中的对。当我使用 [] 运算符时,我在大约 900 的数组大小上遇到了“超出时间限制”。

Mof*_*ofX 3

[] 运算符比 find 慢的原因有两个:

  1. [] 运算符在映射上调用非常量函数,正确防止各种优化,例如循环展开。
  2. 更重要的原因: [] 运算符使用其默认值在地图中创建不存在的元素。地图将因之前不在地图中的所有 A[i] + A[j] 对而膨胀,并将其值设置为 0。这将增加地图大小,从而增加时间。

我认为由于以下一个或多个原因,您的性能测量显示两种替代方案之间没有差异:

  1. 输入向量太小,无法产生影响
  2. A[i] + A[j] 的大多数组合已经在向量中,因此 unordered_map 还没有膨胀到足以产生影响
  3. 您没有优化您的代码(-O3 或 -Os)您的代码