测试std::sort 和std::qsort 的性能, 修改编译器栈大小

根据effective STL中Item 46 提到, C程序员很难接受C++的STL中std::sort(定义于头文件<algorithm>)竟然比C语言的std::qsort(定义与头文件<cstdlib>中)快了670%。 最后Scot Meyer建议我们我们要使用C++的std::sort函数。

我们知道qsort 实现的排序算法是快排, 但是std::sort 实现的排序算法并不知道, 有人说这得看是哪一个STL版本了。 std::sort的大部分实现的是quick sort(也是快排), 或者是一个类似于插入排序的, 结合了快排, 堆排, 以及插入排序的混合算法。 总而言之,sort和qsort的算法复杂度是O(nlogn)。

但是, std::sort更快。 快的原因是运行的时候, sort函数使用inline的方式调用比较函数(comparision function), 然而qsort使用的是指针的方式调用(即function pointer)comparison function。 Meyer称, sort通过使用comparing funcion object(即functor) 作为算法的参数, 使得排序的时间大大降低, 这是一个"abstraction bonus"。

为了体现个算法性能差别, 我们对size很大的数组(大小为10000000(一千万个随机数))排序。测试函数如下:

#include <iostream>
#include <vector>
#include <algorithm>

#include <cstdlib> // for rand() function
#include <ctime> //
#include <cstdio>

const size_t LARGE_SIZE = 1000000;

// functor
struct rnd {
    int operator()() { // overloading ()
        return rand() % LARGE_SIZE; // rand() returns range between 0 and RAND_MAX
    }
};

int comp( const void* a, const void* b ) {
    return ( *( int* )a - *( int* )b ); // casting and then minus, return 0 if equals
}

int main() {
    int ary[LARGE_SIZE];
    int ary_copy[LARGE_SIZE];
    // generate random data
    std::generate( ary, ary + LARGE_SIZE, rnd() );
    std::copy( ary, ary + LARGE_SIZE, ary_copy );
    // get time
    std::time_t start0 = std::clock();
    // perform quick sort C using function pointer
    std::qsort( ary, LARGE_SIZE, sizeof( int ), comp );
    std::time_t end0 = std::clock();
    std::cout << "C quick-sort time elapsed: "
              << static_cast<double>( end0 - start0 ) / CLOCKS_PER_SEC
              << "\n";
    // get time again
    std::time_t start1 = std::clock();
    // perform quick sort C++ using function object
    std::sort( ary_copy, ary_copy + LARGE_SIZE );
    std::time_t end1 = std::clock();
    std::cout << "C++ quick-sort time elapsed: "
    << static_cast<double>( end1 - start1 ) / CLOCKS_PER_SEC << "\n";
}

为了运行该程序, 需要注意一下几点。 NOTE:

(1)由于数组为一千万个int, 占用的栈内存4 * 10MB即40MB的内存, 而一般的compiler的能够分配的栈内存只是1MB, 显然尽管能通过编译, 但是运行的时候, 程序会crashed。 所以我我们需要重新设置stack size。 我使用的IDE是code::blocks, 使用的编译器是Mingw, 我亲自测试了一下, 内存大小栈内存大小仅为1 M 左右, 测试程序如下:

#include <cmath>
#include <iostream>
using namespace std;

int main(void)
{
       const int n = pow(2,20);             // 指数超过20, 程序就crashed
       char arr[n];                              // size(arr) = 1MB
       return 0;
}

扩大占内存的办法如下:

settiings -> compiler -> linker settings , 然后在other  linker options 下面打入如下指令:

-Wl,--stack=100000000

意思是我们将栈的size设置为100MB, 当然可以处理1千万个整数(40MB). 如下图:

ok 即可大功告成。

(2)wait wait, 还要注意一个事情, 就是我们必须release的mode 下面编译, 而不是在debug模式下面进行编译运行。

因为 release mode确保you compiled with all optimizations. 否则会出错, 我在debug 下面测试一些, 结果是qsort会快些, 显示是没有用到abstraction
bonus啊。

注意: Debug通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序.Release称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用.
注意, 下图选择release mode。

接下来开始测试。。。, 如下图:

说明C++中的std::sort更快。

时间: 2024-10-12 04:00:54

测试std::sort 和std::qsort 的性能, 修改编译器栈大小的相关文章

std::sort要求strict weak ordering

strict weak ordering简单地说就是小于语义,非小于等于语义,也就是说对于相等的或者异常的元素比较应当返回false 后果很严重,在google搜一下violating strict weak ordering make std::sort crash能看到很多种后果, 经测试,当待排序元素大于16个时使用std::sort,若传入的callable违反strict weak ordering,则可能死循环也可能越界访问. 待排序元素小于等于16个不会有问题是因为std::sor

将三维空间的点按照座标排序(兼谈为std::sort写compare function的注意事项)

最近碰到这样一个问题:我们从文件里读入了一组三维空间的点,其中有些点的X,Y,Z座标只存在微小的差别,远小于我们后续数据处理的精度,可以认为它们是重复的.所以我们要把这些重复的点去掉.因为数据量不大,这里不准备使用划分包围盒或者建立k-d tree这样的重型武器,我们简单的把点按照其三维坐标进行排序就好. 我们准备使用STL的std::sort来做这个排序.它要求提供一个符合如下签名的比较函数: bool cmp(const Type1 &a, const Type2 &b) 怎么样写这个

GDB实践:一场std::sort引发的coredump

以前只掌握gdb一些基础知识,还没有真正"实战"过.刚好最近同事一个进程coredump了,原因比较深,正好利用这个机会来分析下 // @ 运行:gdb [可执行程序] -c [coredump文件] gdb edu_info_recommend_svr -c core_edu_info_recomm // @ 查看堆栈信息:bt (backtrace) (gdb) bt 10 #0 0x00007fa0809b6144 in __strcmp_sse42 () from /lib64

std::sort源码剖析

文章参考:源码 这篇文章在一个偶然的机会看到,我原先也是知道sort函数效率高,但终究没有去了解原因,读了这篇文章更加钦佩C++大师积年累月智慧的结晶和对效率的极致追求,看到很多地方不禁暗暗称奇.也还是感慨原文作者对技术的追求和细致的讲解,下面的内容大多来自作者的文章,其中加入了自己的理解,也不枉费大半个下午的时间. 从事程序设计行业的朋友一定对排序不陌生,它从我们刚刚接触数据结构课程开始便伴随我们左右,是需要掌握的重要技能.任何一本数据结构的教科书一定会介绍各种各样的排序算法,比如最简单的冒泡

std::string源码探秘和性能分析

std::string源码探秘和性能分析 本文主要讲c++标准库的string的内部实现,以及对象拷贝的性能分析. 文中采用的源码版本为gcc-4.9,测试环境为centos7, x86_64,涉及到指针等数据类型的大小也假定是在64环境位下. stl源码可以在gnu gcc的官方网站下载到:https://gcc.gnu.org/ 头文件 vector头文件,该文件也可以直接在安装了g++的linux系统中找到.主要包含以下头内容: // vector #include <bits/strin

std::sort 学习:一种递归分治方法

// std::sort 学习:一种递归分治方法 今天看了看 stl 的 std::sort 的代码,众所周知,这个函数是在快速排序递归太深的时候使用堆排序防止过度退化,但是今天说的不是这个.我们只看快速排序的部分. 我们一般实现快速排序大概是这样的(本王随意写了个用下标当参数的排序函数,领会意思即可). void quick_sort(int first, int last) // 某个数组的 [first, last) {  if ((last - first) > 1) {  int mi

源码阅读笔记 - 1 MSVC2015中的std::sort

大约寒假开始的时候我就已经把std::sort的源码阅读完毕并理解其中的做法了,到了寒假结尾,姑且把它写出来 这是我的第一篇源码阅读笔记,以后会发更多的,包括算法和库实现,源码会按照我自己的代码风格格式化,去掉或者展开用于条件编译或者debug检查的宏,依重要程度重新排序函数,但是不会改变命名方式(虽然MSVC的STL命名实在是我不能接受的那种),对于代码块的解释会在代码块前(上面)用注释标明. template<class _RanIt, class _Diff, class _Pr> in

[C/C++标准库]_[初级]_[使用std::sort排序各种类型数据]

std::sort 场景: 1. 在使用sort排序时,有时候需要对对象的某个值进行排序,比如对类对象的某个id的int类型值或者bool类型值,其实bool类型值排序研究了半天.. test_sort.cpp #include <stdlib.h> #include <string.h> #include <string> #include <vector> #include <algorithm> #include <iostream&

非常无聊——STD::sort VS 基数排序

众所周知,Std::sort()是一个非常快速的排序算法,它基于快排,但又有所修改.一般来说用它就挺快的了,代码一行,时间复杂度O(nlogn)(难道不是大叫一声"老子要排序!!"就排好了么...).我们也知道,不基于比较的排序可以达到O(n),比如说基数排序.什么,它是O(n * log(10)( max(n) ) ) 的?NO!!我们可以用sqrt(max(n))来作为进制,这样就是(N*logMax(n))=O(2*n)的了..看起来很不错, 代码量嘛....呵呵 所谓基数排序,