【问题标题】:Sorting array of doubles extremely slow, and slower对双精度数组进行排序非常慢,而且更慢
【发布时间】:2013-12-21 04:47:30
【问题描述】:

我正在尝试对双精度数组进行排序。它非常慢:

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;
}

然后我尝试了这个方法 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;
}

有什么更快的吗?

【问题讨论】:

  • 你如何衡量这个?你在看什么样的表演?你在什么硬件上运行它?
  • 什么操作系统,什么编译器?你是如何实现 qsort 的?
  • 我正在使用 VS2010 分析器进行测量。我在双 CPU(英特尔 5690)工作站上运行它,具有 12 个物理内核和 24 个逻辑内核,以及 192 GB(是 gigs,不是 megs)的 ram,以及 1 tb 固态驱动器。 Qsort 是 VS2010 C 库例程。目标是Windows7,64位
  • 对数组进行排序需要多长时间以及如何测量它?在 windows 中启动一个新进程非常耗时,所以如果你测量整个程序的执行时间,你的测量就会关闭。
  • 您是否正在对代码进行优化?我觉得优化后应该是一样的。

标签: c arrays sorting double qsort


【解决方案1】:

我会这样写:

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;
}

这实际上是您的两个建议的混合。请注意,仅仅为了比较单个值而进行回调永远不会达到最佳效率。这是 C 的 qsort() 工作方式的一个缺点;最好在排序中内联比较,但这在 C 中是不可能的。

当然,除非您自己实现排序算法并针对double 值进行定制。

【讨论】:

  • +1:看起来不错,只是您的例行名称需要比“compareDoubles_EvenSlowerMethod”更好的营销。
  • @chux 谢谢,复制粘贴有点太多了。改变了。
  • 抱歉,这只是稍微好一点。分析器报告说,SlowMethod 需要 7 个时间单位来完成,SlowerMethod 需要 24 个,而您的建议需要 20 个单位。
  • 这是 Profiler 报告的“Exclusive Samples %”。无论这些测量单位是什么,很明显,最慢的方法比最快的方法慢 3 倍。即使是最快的也很慢。
  • @user994179 如果可以的话,我会再次对您的帖子进行投票,因为您正在使用分析器来评估事物。通常帖子太主观了。顺便说一句:你列出的大小是多少?
【解决方案2】:

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

int compareDoubles_noBranch(const void *x, const void *y) {
    return -1 * (*(const double*)x < *(const double*)y)
         +  1 * (*(const double*)x > *(const double*)y);
}

如果没有被编译器优化掉的话,做类似const double x = *(const double*)x, ... 的事情可能不是一个好主意,因为内存/复制开销。我不确定,但我认为内联强制转换不会增加任何开销,它们只会影响在内存上调用的 CPU 指令 x 和 y 指向何时调用不等式运算符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-10
    • 2016-08-24
    • 1970-01-01
    • 2012-02-25
    • 2017-01-04
    • 2017-08-01
    • 2014-02-09
    相关资源
    最近更新 更多