首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >std::map:find的效率与值的数据大小有关吗?

std::map:find的效率与值的数据大小有关吗?
EN

Stack Overflow用户
提问于 2017-08-07 11:42:25
回答 1查看 261关注 0票数 1

我使用std::map<std::pair<int, int>, class B>来保存网格地图的信息,B类包含大约10000字节的数据。我发现40000次find操作大约需要10 has,尽管映射只有四个键值。当我将B类的数据大小减少到2500字节时,成本也降低到了3.5ms左右。我知道查找操作的时间复杂度是O(log(N)),造成这种现象的原因是什么?

EN

Stack Overflow用户

回答已采纳

发布于 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>作为映射的值。

可编译测试代码如下:

代码语言:javascript
运行
复制
#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");
}
票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45546092

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档