C 双倍数组的排序速度非常慢,而且更慢

C 双倍数组的排序速度非常慢,而且更慢,c,arrays,sorting,double,qsort,C,Arrays,Sorting,Double,Qsort,我正在尝试对一系列的双打进行排序。速度非常慢: double price[1000]; void sortArrayOfDoubles(double price[ ], int length) { qsort(price, length, sizeof (double), compareDoubles); } 我用这个作为比较方法,速度很慢。称之为方法A: int compareDoubles_SlowMethod(const void*

我正在尝试对一系列的双打进行排序。速度非常慢:

double price[1000];

    void sortArrayOfDoubles(double price[ ], int length)    
    {   
        qsort(price, length, sizeof (double), compareDoubles);
    }
我用这个作为比较方法,速度很慢。称之为方法A:

int compareDoubles_SlowMethod(const void* elem1, const void* elem2)
{
    if(*(const double*)elem1 < *(const double*)elem2)
        return -1;
    return *(const double*)elem1 > *(const double*)elem2;
}
int compareDoubles\u SlowMethod(const void*elem1,const void*elem2)
{
如果(*(常数双*)elem1<*(常数双*)elem2)
返回-1;
返回*(常数双*)elem1>*(常数双*)elem2;
}
然后我尝试了这个方法,方法B,比另一个慢3倍多

int compareDoubles_EvenSlowerMethod(const void *x, const void *y)
{
  double xx = *(double*)x, yy = *(double*)y;
  if (xx < yy) return -1;
  if (xx > yy) return  1;
  return 0;
}
int compareDoubles\u EvenSlowerMethod(const void*x,const void*y)
{
双xx=*(双*)x,yy=*(双*)y;
如果(xxyy)返回1;
返回0;
}
还有更快的吗?

我可以这样写:

static int compareDoubles(const void *px, const void *py)
{
  const double x = *(double *) px, y = *(double *) py;

  if(x < y)
    return -1;
  return x > y;
}
static int compareDoubles(const void*px,const void*py)
{
常数双x=*(双*)px,y=*(双*)py;
if(xy;
}
这基本上是你两个建议的混合。请注意,仅为比较单个值而执行回调永远不会达到最佳效率。这是C的
qsort()
工作方式的一个缺点;最好将比较内联到排序中,但在C中这是不可能的

当然,除非您自己实现排序算法,并为
双值
定制它。

我将其写成:

static int compareDoubles(const void *px, const void *py)
{
  const double x = *(double *) px, y = *(double *) py;

  if(x < y)
    return -1;
  return x > y;
}
static int compareDoubles(const void*px,const void*py)
{
常数双x=*(双*)px,y=*(双*)py;
if(xy;
}
这基本上是你两个建议的混合。请注意,仅为比较单个值而执行回调永远不会达到最佳效率。这是C的
qsort()
工作方式的一个缺点;最好将比较内联到排序中,但在C中这是不可能的


当然,除非您自己实现排序算法,并针对
双值
对其进行调整。

将分支从函数中取出可能会改善其运行时间。例如:

int compareDoubles_noBranch(const void *x, const void *y) {
    return -1 * (*(const double*)x < *(const double*)y)
         +  1 * (*(const double*)x > *(const double*)y);
}
int compareDoubles\u noBranch(常数void*x,常数void*y){
返回-1*(*(常数双*)x<*(常数双*)y)
+1*(*(常数双*)x>*(常数双*)y);
}

如果编译器没有优化内存/复制开销,那么像
constdouble x=*(constdouble*)x,…
这样做可能不是一个好主意。我不确定,但我认为内联类型转换不会增加开销,它们只会影响调用不等式运算符时在内存
x
y
上调用的CPU指令。

从函数中取出分支可能会改善其运行时间。例如:

int compareDoubles_noBranch(const void *x, const void *y) {
    return -1 * (*(const double*)x < *(const double*)y)
         +  1 * (*(const double*)x > *(const double*)y);
}
int compareDoubles\u noBranch(常数void*x,常数void*y){
返回-1*(*(常数双*)x<*(常数双*)y)
+1*(*(常数双*)x>*(常数双*)y);
}


如果编译器没有优化内存/复制开销,那么像
constdouble x=*(constdouble*)x,…
这样做可能不是一个好主意。我不确定,但我认为内联类型转换不会增加开销,它们只会影响调用不等式运算符时在内存
x
y
上调用的CPU指令。

您是如何衡量这一点的?你在看什么样的表演?你在什么硬件上运行这个?什么操作系统,什么编译器?您是如何实现qsort的?我正在使用VS2010分析器进行测量。我在一个双cpu(Intel 5690)工作站上运行它,它有12个物理核和24个逻辑核,192 GB(是gigs,不是megs)的ram和1 tb的固态驱动器。Qsort是VS2010 C库例程。目标是Windows7,64位对数组进行排序需要多长时间?如何测量?在windows中启动一个新进程非常耗时,因此,如果您测量整个程序的执行时间,您的测量将被关闭。您是否正在对代码进行优化?我认为优化后应该是一样的。你是如何衡量这一点的?你在看什么样的表演?你在什么硬件上运行这个?什么操作系统,什么编译器?您是如何实现qsort的?我正在使用VS2010分析器进行测量。我在一个双cpu(Intel 5690)工作站上运行它,它有12个物理核和24个逻辑核,192 GB(是gigs,不是megs)的ram和1 tb的固态驱动器。Qsort是VS2010 C库例程。目标是Windows7,64位对数组进行排序需要多长时间?如何测量?在windows中启动一个新进程非常耗时,因此,如果您测量整个程序的执行时间,您的测量将被关闭。您是否正在对代码进行优化?我认为优化后应该是一样的。+1:看起来不错,只是你的日常名字需要比“compareDoubles\u EvenSlowerMethod”更好的营销手段。@chux谢谢,那是有点太多的复制粘贴了。改变了。对不起,这只是稍微好一点。探查器报告SlowMethod需要7个时间单位才能完成,SlowerMethod需要24个时间单位,您的建议需要20个时间单位。这是探查器报告的“独占样本%”。无论这些测量单位是什么,很明显,最慢的方法比最快的方法慢3倍。即使是速度最快的一个也是慢的。@user994179如果可以的话,我会再次投票给你的帖子,因为你正在使用剖析器来评估事情。帖子往往过于主观。顺便说一句:你的列表大小是多少?+1:看起来不错,不过你的日常名字需要比“compareDoubles\u EvenSlowerMethod”更好的营销手段。@chux谢谢,那是有点太多的复制粘贴了。改变了。对不起,这只是稍微好一点。探查器报告说,SlowMethod需要7个时间单位才能完成,SlowerMethod需要24个时间单位,您的建议需要20个时间单位。这是“独家样本”