为什么Quick Sort的实现比qsort慢?

时间:2015-11-16 00:13:19

标签: c performance sorting quicksort

对算法进行一些更新。我写了这个快速排序实现:

#define SWAP(X, Y, Type) { Type Temp = (X); (X) = (Y); (Y) = Temp; }

int QSPartition(int* Array, int StartIndex, int EndIndex)
{
    int PivotDestinationIndex = StartIndex;
    int Pivot = Array[EndIndex];
    for(int i = StartIndex; i <= EndIndex; i++)
    {
        if (Array[i] < Pivot)
        {
            SWAP(Array[i], Array[PivotDestinationIndex], int);
            PivotDestinationIndex++;
        }
    }
    SWAP(Array[PivotDestinationIndex], Array[EndIndex], int);
    return PivotDestinationIndex;
}

void QuickSort(int* Array, int StartIndex, int EndIndex)
{
    if (StartIndex >= EndIndex)
        return;

    int PivotIndex = QSPartition(Array, StartIndex, EndIndex);
    QuickSort(Array, PivotIndex + 1, EndIndex);
    QuickSort(Array, StartIndex, PivotIndex - 1);
}

在我的主程序中:

#define Measure(Iterations, What, Code)\
{\
    clock_t Begin = clock();\
    for(int _im_ = 0; _im_ < Iterations; _im_++)\
    {\
        Code;\
    }\
    clock_t End = clock();\
    printf("Time took to " What ": %.1f ms\n", (double)(End - Begin));\
}

int CompareInt(const void* x, const void* y) { return *(int*)x - *(int*)y; }

int main()
{
    srand(time(0));

    int Count = 100000;
    int* Array0 = (int*)malloc(sizeof(int) * Count);
    int* Array1 = (int*)malloc(sizeof(int) * Count);

    for (int i = 0; i < Count; i++)
    {
        int RandomValue = rand() % 100;
        Array0[i] = RandomValue;
        Array1[i] = RandomValue;
    }

    Measure(1, "My Quick", QuickSort(Array0, 0, Count - 1));
    Measure(1, "C  Quick", qsort(Array1, Count, sizeof(int), CompareInt));

    getchar();
    return 0;
}

输出结果是“我的快速”始终在125 ms左右,而“C快速”始终在25 ms左右。 (32位DEBUG构建 - 在RELEASE上仍然相同,慢5倍)

发生了什么事?为什么我的实现速度较慢? (我尝试了内联函数,但没有做太多的事情)还有其他错误吗? (我计算时间的方式,或者我用随机值填充数组的方式,还是......?)

1 个答案:

答案 0 :(得分:2)

尝试其中一个,你需要将std :: swap更改为交换C。

使用枢轴中间值的QuickSort:

void QuickSort(uint32_t a[], int lo, int hi) {
    int i = lo, j = hi;
    uint32_t pivot = a[(lo + hi) / 2];
    while (i <= j) {            // partition
        while (a[i] < pivot)
            i++;
        while (a[j] > pivot)
            j--;
        if (i <= j) {
            std::swap(a[i], a[j]);
            i++;
            j--;
        }
    }
    if (lo < j)                 // recurse
        QuickSort(a, lo, j);
    if (i < hi)
        QuickSort(a, i, hi);
}

QuickSort使用低,中,高值的中位数作为支点

void QuickSort(uint32_t a[], int lo, int hi) {
    int i = lo, j = (lo + hi)/2, k = hi;
    uint32_t pivot;
    if (a[k] < a[i])            // median of 3
        std::swap(a[k], a[i]);
    if (a[j] < a[i])
        std::swap(a[j], a[i]);
    if (a[k] < a[j])
        std::swap(a[k], a[j]);
    pivot = a[j];
    while (i <= k) {            // partition
        while (a[i] < pivot)
            i++;
        while (a[k] > pivot)
            k--;
        if (i <= k) {
            std::swap(a[i], a[k]);
            i++;
            k--;
        }
    }
    if (lo < k)                 // recurse
        QuickSort(a, lo, k);
    if (i < hi)
        QuickSort(a, i, hi);
}