【发布时间】:2010-12-11 14:16:46
【问题描述】:
我有一个边数组,它被定义为 C 风格的双精度数组,其中每 4 个双精度定义一个边,如下所示:
double *p = ...;
printf("edge1: %lf %lf %lf %lf\n", p[0], p[1], p[2], p[3]);
printf("edge2: %lf %lf %lf %lf\n", p[4], p[5], p[6], p[7]);
所以我想使用std::sort() 按边长对其进行排序。如果是struct Edge { double x1, y1, x2, y2; }; Edge *p;,我会很高兴。
但是在这种情况下,双精度数组的块大小不是由指针类型表示的。 qsort() 允许您显式指定块大小,但 std::sort() 通过指针类型推断块大小。
出于性能原因(内存使用和 CPU),假设不希望创建新数组或以某种方式转换数组。再次出于性能原因,假设我们确实想使用std::sort() 而不是qsort()。
是否可以调用std::sort() 而不会浪费一个 CPU 周期来转换数据?
可能的方法:
一个明显的方法是尝试强制转换指针:
double *p = ...;
struct Edge { double arr[4]; };
Edge *p2 = reinterpret_cast<Edge*>(p);
std::sort(...);
但是如何确保数据正确对齐?另外,我如何确保它始终在所有平台和架构上正确对齐?
或者我可以使用typedef double[4] Edge;吗?
【问题讨论】:
-
为什么 std::sort 会更快?
-
@Nick Johnson:据我所知,它使用了更好的算法。
-
经验上是这样,大概是因为它可以内联比较。但是,值得首先分析您的应用程序以确定排序是一个值得优化的瓶颈 - qsort 运行良好。
-
拥有 L 全局不会影响线程安全。事实上,如您所见,qsort 接收该参数,但它会将其复制到内部。顺便说一句,std::sort 仅在某些情况下更快,但肯定不是在普通 C 数组上。
-
添加了关于
qsort的注释,因为有很多错误答案。