我使用std::map<std::pair<int, int>, class B>
来保存网格地图的信息,B类包含大约10000字节的数据。我发现40000次find
操作大约需要10 has,尽管映射只有四个键值。当我将B类的数据大小减少到2500字节时,成本也降低到了3.5ms左右。我知道查找操作的时间复杂度是O(log(N)),造成这种现象的原因是什么?
发布于 2017-08-07 16:05:38
我很好奇,于是试了一个简单的测试。测试代码如下(用VS2015编译)。
这就是我在发布版本中运行代码时得到的结果(优化):
Value10k: 0.126498 ms Value2k: 0.121991 ms
这是调试生成中的输出:
Value10k: 120.187 ms Value2k: 95.5364 ms
在版本构建中,差异可以忽略不计;在调试构建中,似乎存在一些差异(尽管,对于性能数据,我倾向于更喜欢发行版构建)。
我不知道map::find
方法的实现细节。无论如何,请注意,大O符号只是故事的一部分。要考虑性能的另一个重要方面是数据的缓存友好性、数据局部性等。
我甚至不知道你的B班是否有一些昂贵的复制操作正在进行。
无论如何,我建议度量您的代码性能,并与其他变体进行比较,比如使用unique_ptr<B>
或shared_ptr<B>
作为映射的值。
可编译测试代码如下:
#include <iostream>
#include <map>
#include <windows.h>
using namespace std;
template <int DimT>
struct Value
{
char Data[DimT];
};
typedef Value<10000> Value10k;
typedef Value<2000> Value2k;
long long Counter()
{
LARGE_INTEGER li;
QueryPerformanceCounter(&li);
return li.QuadPart;
}
long long Frequency()
{
LARGE_INTEGER li;
QueryPerformanceFrequency(&li);
return li.QuadPart;
}
void PrintTime(const long long start, const long long finish, const char * const msg)
{
cout << msg << ": " << (finish - start) * 1000.0 / Frequency() << " ms\n";
}
bool IsEven(int n)
{
return (n % 2) == 0;
}
int main()
{
map<pair<int, int>, Value10k> m1;
m1[make_pair(0, 0)] = Value10k{};
m1[make_pair(0, 1)] = Value10k{};
m1[make_pair(1, 0)] = Value10k{};
m1[make_pair(1, 1)] = Value10k{};
constexpr int searchCount = 40000;
auto start = Counter();
for (int i = 0; i < searchCount; i++)
{
int x{};
int y{};
if (IsEven(i))
{
x = 0;
y = 1;
}
else
{
x = 1;
y = 0;
}
auto search = m1.find(make_pair(x, y));
}
auto finish = Counter();
PrintTime(start, finish, "Value10k");
map<pair<int, int>, Value2k> m2;
m2[make_pair(0, 0)] = Value2k{};
m2[make_pair(0, 1)] = Value2k{};
m2[make_pair(1, 0)] = Value2k{};
m2[make_pair(1, 1)] = Value2k{};
start = Counter();
for (int i = 0; i < searchCount; i++)
{
int x{};
int y{};
if (IsEven(i))
{
x = 0;
y = 1;
}
else
{
x = 1;
y = 0;
}
auto search = m2.find(make_pair(x, y));
}
finish = Counter();
PrintTime(start, finish, "Value2k");
}
https://stackoverflow.com/questions/45546092
复制相似问题