跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • C++ STL 中查找速度最快的是什么数据结构?
未分類
25 11 月 2020

C++ STL 中查找速度最快的是什么数据结构?

C++ STL 中查找速度最快的是什么数据结构?

資深大佬 : black11black 9

如题,C++不太熟,最近有个需求是要把 python 科学计算代码用 C++加速,写的过程中遇到问题就来问 V 友了。

目前要实现一个类似 python 中字典映射的操作,即比如输入 token = “sam” ,要求能够快速的获取到某数据结构(比如说一个 vector )中 sam 对应的指定项。据我所知 vector 原生可以用角标提取,但应该是不支持用字符串提取这种的,即 v[0]这种是 OK 的但是 v[“sam”]这种应该是不行的。

由于我不清楚 stl 容器具体的搜索实现,并不能确定用哪种方式会更快。因为我知道 py 的字典查找经过了 hash 优化,如果 c++不好好选择算法的话,一个搞不好比 python 更慢也是有可能的。

网上搜到一些资料显示 vector 比 set 查找更快,而另一些资料则显示相反,互相矛盾,看不太懂。求问一下 c++带佬,这种常见数据结构在 c++里的最佳实践是什么?

===========================

另外之前 v2 一个老哥似乎说过 map 查找速度超级慢

大佬有話說 (12)

  • 資深大佬 : lcdtyph

    unordered_map

  • 資深大佬 : agagega

    你想要的是 unordered_map

  • 資深大佬 : DGideas

    上正解,另外也别这么黑 map 啊。。。充其量查找速度还是对数时间复杂度呢。。

  • 資深大佬 : secondwtq

    vector 只能整数 index 这只是个接口问题而已,你自己往里面存个 pair 自己写函数查也可以
    C++ 社区的意思是,所有涉及到 pointer chasing 的都慢,所以 std::list 是垃圾,vector FTW
    所以如果数据小的话,就直接用 vector 线性查,可能比其他数据结构还要快,这个叫 flat map (不是 Monad bind 的那个 flatmap )
    另外,vector 还会加一个 SBO 的优化,这样就可以完全避免内存分配,这个叫 small vector

    unordered_map 在性能方面的问题在于它是 chaining 实现的,内存性能一般不如 open addressing,所以有时候会用 open_addressing 的实现,这个叫 dense_map
    unordered_map 的优势在于迭代器稳定,map 的优势在于 ordered access

    至于查字符串还有专门的数据结构

    至于主这个,你得自己 benchmark

  • 主 資深大佬 : black11black

    @secondwtq 大佬再问个事,有关插入,读取和删除的效率。目前需要对一个表类数据结构频繁操作,对应的是 py 的 list,插入,读取,删除我粗略估计在 5:10:3 这样的比例,用 vector 是正确选择吗?因为听说 vec 读取很快,但是删除开销很高。如果用链表的话哪个更合适?

  • 資深大佬 : QBugHunter

    @black11black
    vector 时这样的,比如你要储存 10000 个对象,然后 vector 会申请一块连续的内存,可能可以存放 20000 个(这个值不同版本的 STL 有所不同),然后你要在尾部插入 10 个,或者删除 10 个,速度很快
    但如果你要在尾部再插入 10000 个对象,vector 就会再申请一块 40000 个对象长度的内存,然后把 20000 个对象复制进去

  • 資深大佬 : wctml

    年轻人 你不讲武德,为什么查同一位置;

    “`
    unordered_map<int, float> mapValue;
    clock_t timeStart = clock();
    for (size_t index(0); index < 10000000; ++index)
    {
    mapValue[index] = 1000000 – index;
    }
    std::cout << “make time ” << (clock() – timeStart) << std::endl;
    double sum(0);
    timeStart = clock();
    for (size_t index(0); index < 10000000; ++index)
    {
    sum += mapValue[9999999];
    }
    std::cout << “find time ” << (clock() – timeStart) << std::endl;

    sum = 0;
    timeStart = clock();
    for (size_t index(0); index < 10000000; ++index)
    {
    const auto& iter = mapValue.find(9999999);
    if (iter != mapValue.end())
    {
    sum += iter->second;
    }
    }
    std::cout << “find time ” << (clock() – timeStart) << std::endl;
    “`

    make time 3432
    find time 39
    find time 7

  • 主 資深大佬 : black11black

    @wctml 这方代码啥意思大佬,uo_map 的搜索比索隐快的多的意思吗?

  • 主 資深大佬 : black11black

    有需要大量用到排序的数据结构,网上查了查似乎是 deque 最快,然而实测还是 vector 快,序列长度在一万左右。也是神秘

  • 資深大佬 : wctml

    @black11black
    1 、这是 C++坑的地方,在不同的用法,有不同的区别。这点不像 python 做一个事情可能只有一个最优解,但是 C++可能有 N 个解法得你去踩坑。
    2 、可以了解 C ++中的 map []和 map.at 的区别;
    3 、另外查找同一个位置可能编译器会有优化的,可以试试伪随机搜索效率测试。

  • 資深大佬 : wctml

    sum = 0;
    timeStart = clock();
    for (size_t index(0); index < 10000000; ++index)
    {
    sum += mapValue.at(9999999);
    }
    std::cout << “find time ” << (clock() – timeStart) << std::endl;

    find time 7

  • 資深大佬 : wctml

    “`
    sum = 0;
    timeStart = clock();
    for (size_t index(0); index < 10000000; ++index)
    {
    sum += mapValue 。at(9999999);
    }
    std::cout << “find time ” << (clock() – timeStart) << std::endl;

    find time 7
    “`

    请不要在每一个回复中都包括外链,这看起来像是在 spamming
    我只能把点换成句号

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具