qsort_b 和 qsort

Posted

技术标签:

【中文标题】qsort_b 和 qsort【英文标题】:qsort_b and qsort 【发布时间】:2012-12-04 07:30:44 【问题描述】:

在 Mac 上用 C++ 编写一个演示不同排序算法的程序。我找到了两个快速排序实现,qsort 和 qsort_b。

第一个当然是老式的、随处可见的 qsort。但是有 qsort_b,它接受一个块而不是一个函数。这是我的代码:

#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <cstdio>
#include <ctime>

#define DATA 1000000

using namespace std;

int compare(const void* a, const void* b)

    return *(int*)a - *(int*)b;


int main(int argc, char *argv[])

    int* array = new int[DATA];

    srand(time(0));

    for ( int i = 0 ; i < DATA ; ++ i )
    
        array[i] = rand() % 2147483647;
    

    clock_t begin = clock();

    qsort(array, DATA, sizeof(array[0]), compare);
    //qsort_b(array, DATA, sizeof(array[0]), ^(const void* a, const void* b)  return *(int*)a - *(int*)b; );

    clock_t end = clock();

    cout << "Time it takes to sort " << DATA << " integers with quicksort: " << end - begin;

在这里我看到了很大的速度差异,是什么导致了所有这些差异。据我了解,块用于并行处理,在这种情况下不会比函数快。没有什么可以并行处理的,是吗?

编辑:heapsort_b()、mergesort_b() 和 qsort_b() 例程就像没有 _b 后缀的相应例程一样,期望比较回调是块指针而不是函数指针。 (FROM BSD MAN PAGE)

编辑:速度差异。 DATA 为 1000000,qsort 在 146832 ns 内完成,qsort_b 在 127391 ns 内完成。考虑到它快 10% 左右,这是一个相对较大的差异。

编辑:我已经编辑了代码,使其可以拥有更大的整数数组。我个人最大的测试结果是 100000000 个整数,28136278 (28s) vs. 23870078 (24s)。这对我来说差别很大。

【问题讨论】:

您能否详细说明“速度差异大” @KarthikT 我不确定测量单位,但我认为它是纳秒。 qsort 是 146832,qsort_b 是 127391。DATA 是 1000000。 我已经用更大的数据(100000000 个整数)对其进行了测试。这是 28136278 (28s) 与 23870078 (24s)。这对我来说有很大的不同。 似乎是non-standard function,因为这是我能找到的关于这个“qsort_b”的唯一提及。 @Rapptz 你是对的,它是非标准的,它只出现在我的 Mac 上。我可以在我提供的链接中的 BSD 手册中找到它的参考。 【参考方案1】:

Objective-C Block 是另一种动物。它可能看起来像MACRO(编译前替换)和inline functions(告诉编译器“尽你所能消除函数调用开销”),但整体结构与这些结构有很大不同.

块是一个对象,此外,一个堆栈对象。唯一允许在堆栈中创建的对象(至少没有一些技巧)。

当在堆栈中创建Block 对象时,编译器添加所有局部变量、块变量、它引用的读/写变量的地址以及指向块可执行代码的指针。因此,即使在开始执行之前,一切都已准备好进行计算,无需任何堆栈操作。

所以,这不是优化问题,而是Block 的属性。它没有堆栈变量的PUSHPOP的任何函数调用开销。

作为对您的问题的回答,qsort()qsort_b() 没有任何算法差异,而是详细的结构,block vs function

【讨论】:

【参考方案2】:

对我来说看起来像是优化差异。使用 qsort_b,编译器可能会内联比较,而使用 qsort 则不会。区别在于每次比较的函数调用开销。

【讨论】:

你一定是对的。如果我错了,请纠正我,在这种特殊情况下,块就像内联函数。并且内联函数被认为比函数更快。 (***.com/questions/4016061/…) @ShaneHsu 除了我刚才从en.wikipedia.org/wiki/Blocks_(C_language_extension) 读到的内容之外,我对这些“块”一无所知,因此无法评论编译器为它们生成的代码类型。如果您想真正了解发生了什么,请添加编译器命令行开关以生成两种情况的 asm 源文件(而不是目标文件)并进行比较。另一个实验可能是在关闭优化的情况下尝试这两个版本,然后将其调到最大,看看它如何影响相对性能。 稍后会做这个实验。谢谢! 如果qsort_b 是以编译形式存在于系统中的库函数,我看不出它如何内联对块的调用。也许qsort_b 只是使用了更好的排序算法,或者块有更有效的调用约定?

以上是关于qsort_b 和 qsort的主要内容,如果未能解决你的问题,请参考以下文章

qsort函数sort函数

qsort函数sort函数 (精心整理篇)(转载)

在 C 中使用 qsort 时的警告

& 和 && 区别和联系,| 和 || 区别和联系

第三十一节:扫盲并发和并行同步和异步进程和线程阻塞和非阻塞响应和吞吐等

shell中$()和 ` `${}${!}${#}$[] 和$(()),[ ] 和(( ))和 [[ ]]