您的位置:首页 > 其它

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

2015-03-03 18:36 363 查看
根据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 = 10000000;

// 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
;                              // 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更快。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: