各种闲着没事的 STL 数据结构实现排序效率对比

发布时间 2023-10-31 10:18:35作者: RainPPR

各种闲着没事的 STL 数据结构实现排序效率对比

本文出现在这里的原因:

  • 直接原因:@Ju_Ruo_ 在某需要排序的题目里使用了 priority_queue
  • 根本原因:不知道。

太长不看

题目:P1177 【模板】排序

语言环境:C++14 (GCC 9) + O2

排序函数:sort(...) [本文不评测各种 STL 的排序算法的对比

\[\def\arraystretch{1.22} \begin{array}{|r|r|r|} \hline &\mathbb{用时}&\mathbb{内存}\\ \hline \text{C 风格数组}&51\text{ ms}&832.00\text{ KB}\\ \hline \text{std::vector 固定分配}&50\text{ ms}&880.00\text{ KB}\\ \hline \text{std::vector 动态分配}&54\text{ ms}&1.08\text{ MB}\\ \hline \text{std::priority\_queue}&64\text{ ms}&1.09\text{ MB}\\ \hline \text{\_\_gnu\_pbds::priority\_queue}&91\text{ ms}&5.02\text{ MB}\\ \hline \text{std::map 桶排}&101\text{ ms}&4.99\text{ MB}\\ \hline \text{std::multiset}&123\text{ ms}&5.10\text{ MB}\\ \hline \end{array} \]

结论:C 风格数组、vector 固定分配最优;multiset 最劣;pbds 似乎并不强。

评测记录

0x01 -C 风格数组 https://www.luogu.com.cn/record/132486042
0x02 std::vector 固定分配 https://www.luogu.com.cn/record/132485697
0x03 std::vector 动态分配 https://www.luogu.com.cn/record/132485406
0x04 std::priority_queue https://www.luogu.com.cn/record/132486469
0x05 __gnu_pbds::priority_queue https://www.luogu.com.cn/record/132494980
0x06 std::map 桶排 https://www.luogu.com.cn/record/132487867
0x07 std::multiset https://www.luogu.com.cn/record/132486270

评测代码

#include <bits/extc++.h>

using std::sort;
using std::vector;
using std::greater;

#define rep(i, n) for (int i = 0; i < int(n); ++i)

const int N = 1e5 + 10;

#define rr read()
inline int read() {
    int num = 0, flag = 0, ch = getchar();
    for (; !isdigit(ch); ch = getchar()) flag |= ch == '-';
    for (; isdigit(ch); ch = getchar()) num = (num << 1) + (num << 3) + ch - '0';
    return flag ? -num : num;
}

namespace s1 {
    int n, a[N];
    void Main() {
        n = rr; rep(i, n) a[i] = rr;
        sort(a, a + n);
        rep(i, n) printf("%d ", a[i]);
    }
}

namespace s2 {
    void Main() {
        int n = rr; vector<int> a(n);
        rep(i, n) a[i] = rr;
        sort(a.begin(), a.end());
        for (auto i : a) printf("%d ", i);
    }
}

namespace s3 {
    void Main() {
        int n = rr; vector<int> a;
        rep(i, n) a.push_back(rr);
        sort(a.begin(), a.end());
        for (auto i : a) printf("%d ", i);
    }
}

namespace s4 {
    void Main() {
        int n = rr; std::priority_queue<int, vector<int>, greater<int>> heap;
        rep(i, n) heap.push(rr);
        while (heap.size()) printf("%d ", heap.top()), heap.pop();
    }
}

namespace s5 {
    void Main() {
        int n = rr; __gnu_pbds::priority_queue<int, greater<int>> heap;
        rep(i, n) heap.push(rr);
        while (heap.size()) printf("%d ", heap.top()), heap.pop();
    }
}

namespace s6 {
    void Main() {
        int n = rr; std::map<int, int> a;
        rep(i, n) ++a[rr];
        for (auto &i : a) while (i.second--) printf("%d ", i.first);
    }
}

namespace s7 {
    void Main() {
        int n = rr; std::multiset<int> a;
        rep(i, n) a.insert(rr);
        for (auto i : a) printf("%d ", i);
    }
}

signed main() {
    return 0;
}