在实践中,std::sort 和 std::stable_sort 之间的性能差距有多大?

2024-01-25

两者都应该以 O(n log n) 的速度运行,但一般来说排序比 stable_sort 更快。实践中的性能差距有多大?你对此有一些经验吗?

我想要对大量大小约为 20 字节的结构进行排序。对于我来说,结果的稳定性很好,但这不是必须的。目前底层容器是一个普通数组,也许稍后可以将其更改为 std::deque。


有很好的答案从理论上比较了算法。我进行了基准测试std::sort and std::stable_sort with 谷歌/基准 http://github.com/google/benchmark为了好奇心。

提前指出这一点很有用;

  • 基准机有1 X 2500 MHz CPU and 1 GB RAM
  • 基准操作系统Arch Linux 2015.08 x86-64
  • 基准编译使用g++ 5.3.0 and clang++ 3.7.0 (-std=c++11, -O3 and -pthread)
  • BM_Base*基准测试试图测量填充时间std::vector<>。为了更好的比较,应该从排序结果中减去该时间。

第一个基准排序std::vector<int> with 512k size.

[ g++ ]# benchmark_sorts --benchmark_repetitions=10
Run on (1 X 2500 MHz CPU )
2016-01-08 01:37:43
Benchmark                         Time(ns)    CPU(ns) Iterations
----------------------------------------------------------------
...
BM_BaseInt/512k_mean              24730499   24726189         28
BM_BaseInt/512k_stddev              293107     310668          0
...
BM_SortInt/512k_mean              70967679   70799990         10
BM_SortInt/512k_stddev             1300811    1301295          0
...
BM_StableSortInt/512k_mean        73487904   73481467          9
BM_StableSortInt/512k_stddev        979966     925172          0
[ clang++ ]# benchmark_sorts --benchmark_repetitions=10
Run on (1 X 2500 MHz CPU )
2016-01-08 01:39:07
Benchmark                         Time(ns)    CPU(ns) Iterations
----------------------------------------------------------------
...
BM_BaseInt/512k_mean              26198558   26197526         27
BM_BaseInt/512k_stddev              320971     348314          0
...
BM_SortInt/512k_mean              70648019   70666660         10
BM_SortInt/512k_stddev             2030727    2033062          0
...
BM_StableSortInt/512k_mean        82004375   81999989          9
BM_StableSortInt/512k_stddev        197309     181453          0

第二基准排序std::vector<S> with 512k size (sizeof(Struct S) = 20).

[ g++ ]# benchmark_sorts --benchmark_repetitions=10
Run on (1 X 2500 MHz CPU )
2016-01-08 01:49:32
Benchmark                         Time(ns)    CPU(ns) Iterations
----------------------------------------------------------------
...
BM_BaseStruct/512k_mean           26485063   26410254         26
BM_BaseStruct/512k_stddev           270355     128200          0
...
BM_SortStruct/512k_mean           81844178   81833325          8
BM_SortStruct/512k_stddev           240868     204088          0
...
BM_StableSortStruct/512k_mean    106945879  106857114          7
BM_StableSortStruct/512k_stddev   10446119   10341548          0
[ clang++ ]# benchmark_sorts --benchmark_repetitions=10
Run on (1 X 2500 MHz CPU )
2016-01-08 01:53:01
Benchmark                         Time(ns)    CPU(ns) Iterations
----------------------------------------------------------------
...
BM_BaseStruct/512k_mean           27327329   27280000         25
BM_BaseStruct/512k_stddev           488318     333059          0 
...
BM_SortStruct/512k_mean           78611207   78407400          9
BM_SortStruct/512k_stddev           690207     372230          0 
...
BM_StableSortStruct/512k_mean    109477231  109333325          8
BM_StableSortStruct/512k_stddev   11697084   11506626          0

任何喜欢运行基准测试的人,这里是代码,

#include <vector>
#include <random>
#include <algorithm>

#include "benchmark/benchmark_api.h"

#define SIZE 1024 << 9

static void BM_BaseInt(benchmark::State &state) {
  std::random_device rd;
  std::mt19937 mt(rd());
  std::uniform_int_distribution<int> dist;

  while (state.KeepRunning()) {
    std::vector<int> v;
    v.reserve(state.range_x());
    for (int i = 0; i < state.range_x(); i++) {
      v.push_back(dist(mt));
    }
  }
}
BENCHMARK(BM_BaseInt)->Arg(SIZE);

static void BM_SortInt(benchmark::State &state) {
  std::random_device rd;
  std::mt19937 mt(rd());
  std::uniform_int_distribution<int> dist;

  while (state.KeepRunning()) {
    std::vector<int> v;
    v.reserve(state.range_x());
    for (int i = 0; i < state.range_x(); i++) {
      v.push_back(dist(mt));
    }

    std::sort(v.begin(), v.end());
  }
}
BENCHMARK(BM_SortInt)->Arg(SIZE);

static void BM_StableSortInt(benchmark::State &state) {
  std::random_device rd;
  std::mt19937 mt(rd());
  std::uniform_int_distribution<int> dist;

  while (state.KeepRunning()) {
    std::vector<int> v;
    v.reserve(state.range_x());
    for (int i = 0; i < state.range_x(); i++) {
      v.push_back(dist(mt));
    }

    std::stable_sort(v.begin(), v.end());
  }
}
BENCHMARK(BM_StableSortInt)->Arg(SIZE);


struct S {
  int key;
  int arr[4];
};

static void BM_BaseStruct(benchmark::State &state) {
  std::random_device rd;
  std::mt19937 mt(rd());
  std::uniform_int_distribution<int> dist;

  while (state.KeepRunning()) {
    std::vector<S> v;
    v.reserve(state.range_x());
    for (int i = 0; i < state.range_x(); i++) {
      v.push_back({dist(mt)});
    }
  }
}
BENCHMARK(BM_BaseStruct)->Arg(SIZE);

static void BM_SortStruct(benchmark::State &state) {
  std::random_device rd;
  std::mt19937 mt(rd());
  std::uniform_int_distribution<int> dist;

  while (state.KeepRunning()) {
    std::vector<S> v;
    v.reserve(state.range_x());
    for (int i = 0; i < state.range_x(); i++) {
      v.push_back({dist(mt)});
    }

    std::sort(v.begin(), v.end(),
              [](const S &a, const S &b) { return a.key < b.key; });
  }
}
BENCHMARK(BM_SortStruct)->Arg(SIZE);

static void BM_StableSortStruct(benchmark::State &state) {
  std::random_device rd;
  std::mt19937 mt(rd());
  std::uniform_int_distribution<int> dist;

  while (state.KeepRunning()) {
    std::vector<S> v;
    v.reserve(state.range_x());
    for (int i = 0; i < state.range_x(); i++) {
      v.push_back({dist(mt)});
    }

    std::stable_sort(v.begin(), v.end(),
                     [](const S &a, const S &b) { return a.key < b.key; });
  }
}
BENCHMARK(BM_StableSortStruct)->Arg(SIZE);


BENCHMARK_MAIN();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在实践中,std::sort 和 std::stable_sort 之间的性能差距有多大? 的相关文章

  • 在哪里可以找到列出 SSE 内在函数操作的官方参考资料?

    是否有官方参考列出了 GCC 的 SSE 内部函数的操作 即 头文件中的函数 除了 Intel 的 vol 2 PDF 手册外 还有一个在线内在指南 https www intel com content www us en docs in
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • 查找c中结构元素的偏移量

    struct a struct b int i float j x struct c int k float l y z 谁能解释一下如何找到偏移量int k这样我们就可以找到地址int i Use offsetof 找到从开始处的偏移量z
  • Asp.NET WebApi 中类似文件名称的路由

    是否可以在 ASP NET Web API 路由配置中添加一条路由 以允许处理看起来有点像文件名的 URL 我尝试添加以下条目WebApiConfig Register 但这不起作用 使用 URIapi foo 0de7ebfa 3a55
  • Java按日期升序对列表对象进行排序[重复]

    这个问题在这里已经有答案了 我想按一个参数对对象列表进行排序 其日期格式为 YYYY MM DD HH mm 按升序排列 我找不到正确的解决方案 在 python 中使用 lambda 很容易对其进行排序 但在 Java 中我遇到了问题 f
  • BitTorrent 追踪器宣布问题

    我花了一点业余时间编写 BitTorrent 客户端 主要是出于好奇 但部分是出于提高我的 C 技能的愿望 我一直在使用理论维基 http wiki theory org BitTorrentSpecification作为我的向导 我已经建
  • 在 ASP.NET 5 中使用 DI 调用构造函数时解决依赖关系

    Web 上似乎充斥着如何在 ASP NET 5 中使用 DI 的示例 但没有一个示例显示如何调用构造函数并解决依赖关系 以下只是众多案例之一 http social technet microsoft com wiki contents a
  • 创建链表而不将节点声明为指针

    我已经在谷歌和一些教科书上搜索了很长一段时间 我似乎无法理解为什么在构建链表时 节点需要是指针 例如 如果我有一个节点定义为 typedef struct Node int value struct Node next Node 为什么为了
  • WCF 中 SOAP 消息的数字签名

    我在 4 0 中有一个 WCF 服务 我需要向 SOAP 响应添加数字签名 我不太确定实际上应该如何完成 我相信响应应该类似于下面的链接中显示的内容 https spaces internet2 edu display ISWG Signe
  • 如何设计以 char* 指针作为类成员变量的类?

    首先我想介绍一下我的情况 我写了一些类 将 char 指针作为私有类成员 而且这个项目有 GUI 所以当单击按钮时 某些函数可能会执行多次 这些类是设计的单班在项目中 但是其中的某些函数可以执行多次 然后我发现我的项目存在内存泄漏 所以我想
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 如何查看网络连接状态是否发生变化?

    我正在编写一个应用程序 用于检查计算机是否连接到某个特定网络 并为我们的用户带来一些魔力 该应用程序将在后台运行并执行检查是否用户请求 托盘中的菜单 我还希望应用程序能够自动检查用户是否从有线更改为无线 或者断开连接并连接到新网络 并执行魔
  • Windows 窗体:如果文本太长,请添加新行到标签

    我正在使用 C 有时 从网络服务返回的文本 我在标签中显示 太长 并且会在表单边缘被截断 如果标签不适合表单 是否有一种简单的方法可以在标签中添加换行符 Thanks 如果您将标签设置为autosize 它会随着您输入的任何文本自动增长 为
  • zsh 问题:在提示符附近显示最新的文件和目录以及建议的最新文件或目录

    在 MacOS Big Sur 11 3 上 这是我的 zshrc 我想获取最新的修改或创建靠近提示的文件和目录 从最新到最旧的排序 这是我当前的配置 zshrc ZSH completion autoload Uz compinit co
  • 向现有 TCP 和 UDP 代码添加 SSL 支持?

    这是我的问题 现在我有一个 Linux 服务器应用程序 使用 C gcc 编写 它与 Windows C 客户端应用程序 Visual Studio 9 Qt 4 5 进行通信 是什么very在不完全破坏现有协议的情况下向双方添加 SSL
  • 使用其构造函数初始化 OrderedDict 以便保留初始数据的顺序的正确方法?

    初始化有序字典 OD 以使其保留初始数据的顺序的正确方法是什么 from collections import OrderedDict Obviously wrong because regular dict loses order d O
  • 测试用例执行完成后,无论是否通过,如何将测试用例结果保存在变量中?

    我正在使用 NUNIT 在 Visual Studio 中使用 Selenium WebDriver 测试用例的代码是 我想在执行测试用例后立即在变量中记录测试用例通过或失败的情况 我怎样才能实现这一点 NUnit 假设您使用 NUnit
  • IEnumreable 动态和 lambda

    我想在 a 上使用 lambda 表达式IEnumerable
  • C++ 中类级 new 删除运算符的线程安全

    我在我的一门课程中重新实现了新 删除运算符 现在我正在使我的代码成为多线程 并想了解这些运算符是否也需要线程安全 我在某处读到 Visual Studio 中默认的 new delete 运算符是线程安全的 但这对于我的类的自定义 new
  • 如何防止用户控件表单在 C# 中处理键盘输入(箭头键)

    我的用户控件包含其他可以选择的控件 我想实现使用箭头键导航子控件的方法 问题是家长控制拦截箭头键并使用它来滚动其视图什么是我想避免的事情 我想自己解决控制内容的导航问题 我如何控制由箭头键引起的标准行为 提前致谢 MTH 这通常是通过重写

随机推荐

  • Azure PHP SDK:在单个 zip 文件中下载容器的所有 blob

    我想将指定容器中的所有 blob 下载为 zip 文件 有没有办法直接从 Azure 下载 zip 文件 而不需要在我的服务器上处理它 目前我的想法如下 file put contents file name get file conten
  • 以 Zend Repo 作为源,从 master 制作本地 Git 存储库

    我想在测试服务器上克隆主分支 在该服务器上运行主分支和测试站点 此存储库是 Zend PHP 框架应用程序 在配置文件中 home me public html domain com ZendSkeletonApplication git
  • 突出显示根目录的父路径

    我尝试通过更改节点和链接的填充来突出显示从鼠标所在的节点到根节点的路径 我正在使用 Mike s 的 Radial Tidy TreeBlock https bl ocks org mbostock 4063550 我尝试过node anc
  • 使用 Spring MVC 流式传输可关闭资源

    读完后本文 https www airpair com java posts spring streams memory efficiency 我希望使用 Spring 将数据库查询结果直接流式传输到 JSON 响应 以确保恒定的内存使用量
  • 禁用 mod_deflate 和 mod_gzip 压缩 HTML、CSS 和 JS 的最佳方法

    我在运行 Apache 2 的共享主机上有几个站点 我想压缩传送到浏览器的 HTML CSS 和 Javascript 主机已禁用 mod deflate 和 mod gzip 因此这些选项无效 不过 我确实有 PHP 5 所以我可以使用它
  • 通过累积串联将嵌套列表转换为非嵌套列表

    我想像这样转换嵌套列表 l lt list A list a list 1 b list 2 B list cd list c list 3 4 5 d list 6 7 8 e list c 9 10 进入列表 o lt list A c
  • 通过 ODBC“十进制值缩放导致数据截断”

    当我尝试在 MS Access 中查看 ODBC 表时 收到错误 十进制值缩放导致数据截断 我知道返回错误的字段 并且 Access 在查询时能够识别该字段 但我无法查看结果 Error记录 并且错误不断出现 我试过了CDbl 没有运气 A
  • 停止 IntentService 的正确方法

    我正在使用 IntentService 将图像上传到服务器 我的问题是我不知道如何 何时停止服务 当我在 onHandleIntent Intent 中调用 stopself 时 所有在 IntentService 队列中等待的 Inten
  • Typescript 模块创建 AMD 与 Common JS

    任何 Typescript 专家都可以澄清一下在使用 Typescript 时何时以及为何选择 AMD 与 Common JS 来创建模块吗 AMD 用于浏览器 例如 RequireJS 原因是它允许并行下载文件 因为网络延迟是主要瓶颈 C
  • 创建 HTML(PHP 或 Jquery)的最佳实践?

    我有一个 JavaScript 对象 其中包含一些信息 我可以想到两个选项来从这个对象创建 HTML 我想知道哪一种是正确的做事方式 这只是所有偏好吗 1 使用 JavaScript 循环遍历这个数组并使用 Jquery 创建 HTML 2
  • 生成 10000 位随机序列

    有没有比在循环中附加 0 和 1 更有效的方法来在 Python 中生成 10 kBit 10 000 位 随机二进制序列 如果您想要一个随机二进制序列 那么生成适当范围内的随机整数可能是最快的 import random s random
  • 实时卡中的 OpenGL?

    我一直在研究 glass GDK 和 glass 原生 Java 开发 我有一个在 Glass 上运行良好的开放 GL 应用程序 使用标准 Android 约定 我希望将其移植到 GDK 以利用语音触发器等功能 虽然我当然可以轻松地将它用作
  • 从哪里开始学习 Linux DMA/设备驱动/内存分配

    我正在移植 调试设备驱动程序 由另一个内核模块使用 并面临死胡同 因为 dma sync single for device 因内核错误而失败 我不知道这个函数应该做什么 而且谷歌搜索也没有什么帮助 所以我可能需要了解更多关于这个东西的知识
  • 正则表达式删除记事本++中标签之间的文本

    我有这样的代码
  • 我的 iframe 无法与 UIWebView 配合使用

    我已经测试过我的iframe到处都运行得很好 但是iOS in Objective C 它不起作用UIWebView 这是我的代码 有人可以帮助我吗 谢谢 self webView scrollView scrollEnabled NO N
  • 目录中所有文件内容的总大小[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 当我使用ls or du 我得到每个文件占用的磁盘空间量 我需要打开每个文件并计算字节数时得到的文件和子目录中所有数据的总和 如果我能在不
  • 如何扩展 LoginUrlAuthenticationEntryPoint 或如何实现 AuthenticationEntryPoint

    我正在尝试这样做 让 spring security 在登录页面的查询字符串中添加 return to url https stackoverflow com q 4696905 即 让spring告诉登录页面我来自哪里 我有一些 SSO
  • 在 Yii 的控制器中创建构造方法

    我刚刚开始学习Yii 我在那里创建了一个PostController控制器 在这个控制器中 我有一个使用要求Sessions 所以我创建了一个构造函数方法 其代码如下 public session public function const
  • open() 不适用于隐藏文件 python

    我想使用 python 在隐藏文件夹中创建并写入 txt 文件 我正在使用这段代码 file name hi txt temp path myfolder docs file name file open temp path w file
  • 在实践中,std::sort 和 std::stable_sort 之间的性能差距有多大?

    两者都应该以 O n log n 的速度运行 但一般来说排序比 stable sort 更快 实践中的性能差距有多大 你对此有一些经验吗 我想要对大量大小约为 20 字节的结构进行排序 对于我来说 结果的稳定性很好 但这不是必须的 目前底层