【发布时间】:2021-11-03 00:05:43
【问题描述】:
我正在尝试为std::unordered_set、std::set 和std::vector 计时std::find() 函数。但结果对我来说很奇怪。
在unordered_set 中查找元素比在vector 中查找元素需要更多时间。
理论上,搜索的时间复杂度应该是O(1) 对应unordered_set 和O(n) 对应vector。
那么,在unordered_set 中查找元素是否比vector 更快?我是不是做错了什么?
这是我的代码:
#include <iostream>
#include <vector>
#include <set>
#include <unordered_set>
#include <algorithm>
#include <random>
#include <numeric>
#include <chrono>
using namespace std;
int main(int argc, char** argv)
{
int size = 10000;
vector<int> items(size);
iota(items.begin(), items.end(), 0);
auto rng = default_random_engine {};
shuffle(items.begin(), items.end(), rng);
chrono::steady_clock::time_point begin, end;
unordered_set<int> unsetInt;
set<int> setInt;
vector<int> vecInt;
// add element
for(auto it = items.begin(); it != items.end(); it++)
{
unsetInt.insert(*it);
setInt.insert(*it);
vecInt.push_back(*it);
}
// lookup time for unordered_set<int>
begin = chrono::steady_clock::now();
for(int i = 0; i < size; i++)
{
find(unsetInt.begin(), unsetInt.end(), i);
}
end = chrono::steady_clock::now();
cout << "lookup time for unordered_set<int>: " <<
chrono::duration_cast<chrono::milliseconds>(end-begin).count() << "ms" << endl;
// lookup time for set<int>
begin = chrono::steady_clock::now();
for(int i = 0; i < size; i++)
{
find(setInt.begin(), setInt.end(), i);
}
end = chrono::steady_clock::now();
cout << "lookup time for set<int>: " <<
chrono::duration_cast<chrono::milliseconds>(end-begin).count() << "ms" << endl;
// lookup time for vector<int>
begin = chrono::steady_clock::now();
for(int i = 0; i < size; i++)
{
find(vecInt.begin(), vecInt.end(), i);
}
end = chrono::steady_clock::now();
cout << "lookup time for vector<int>: " <<
chrono::duration_cast<chrono::milliseconds>(end-begin).count() << "ms" << endl;
return 0;
}
这是我的结果:
lookup time for unordered_set<int>: 2293ms
lookup time for set<int>: 3080ms
lookup time for vector<int>: 1311ms
【问题讨论】:
-
这些 Big-O 语句总是以“有一个
n_0所以所有n > n_0...”开头。您的n可能远低于该限制。至少,您需要增加n值的趋势,而不仅仅是您假设“它会足够大”的趋势。