使用 swap 作为函数而不是在算法本身内更快地编码

Code faster with swap as function rather than within the algorithm itself

本文关键字:编码 算法 swap 函数 使用      更新时间:2023-10-16

所以我一直在测试C中排序算法的运行时间,并且我一直对代码进行轻微修改,看看它将如何影响速度等,其中一种修改是在排序算法中进行气泡排序交换,而不是单独的函数调用,我希望这样会更快,因为函数调用会在那里打开自己的堆栈帧, 但结果几乎慢了两倍,我不知道为什么。

这是代码:

void Swap(int& x, int& y)
{
    int temp = x;
    x = y;
    y = temp;
}
void BubbleSort(int data[], int size)
{
    int i, j, temp;
    bool is_sorted = false;
    for (i = 0; i < (size - 1) && !is_sorted; i++)
    {
        is_sorted = true;
        for (j = size - 1; j > i; j--)
            if (data[j] < data[j - 1])
            {
                //used to be swap(data[j],data[j-1];
                temp = data[j];
                data[j] = data[j - 1];
                data[j-1] = temp;
                is_sorted = false;
            }
    }
}
  • 编辑以回答评论,是的,我确实在发布时运行了编译器优化,如果您想查看我是如何获得运行时间的,这里是完整的代码 https://gist.github.com/anonymous/7363330

我的猜测是,当temp变量在函数中时,编译器会将其优化,并且交换被识别为它是什么。但是如果没有该函数,temp变量的范围会扩展到使用它的块之外,因此如果没有足够的优化级别,编译器可能总是在其中存储最后一个"临时"值。

尝试将temp声明从循环外部移动到使用它的位置,即 int temp = data[j]

无论如何,这只是一个猜测;看看生产的组件来验证。

我希望这样会更快,因为函数调用打开了 有自己的堆栈帧

期望Swap被内联是完全合理的。在这种情况下,编译器执行的操作基本上与您手动执行的操作相同,并且两个版本之间没有区别。

事实上,我已经检查了您在 SO 上发布的代码,包括 clang 3.4(主干)和 gcc 4.7.2,优化级别为 -O3,并且交换的两个版本之间绝对没有区别Swap函数与手动内联交换)。

这是我的代码:

#include <algorithm>
#include <cstdio>
#include <numeric>
#include <vector>
#include <boost/chrono.hpp>
void Swap(int& x, int& y)
{
    int temp = x;
    x = y;
    y = temp;
}
void BubbleSort(int data[], int size)
{
    int i, j, temp;
    bool is_sorted = false;
    for (i = 0; i < (size - 1) && !is_sorted; i++)
    {
        is_sorted = true;
        for (j = size - 1; j > i; j--)
            if (data[j] < data[j - 1])
            {
                Swap(data[j],data[j-1]);
                //temp = data[j];
                //data[j] = data[j - 1];
                //data[j-1] = temp;
                is_sorted = false;
            }
    }
}
int main() {
    const int SIZE = 30000;
    std::vector<int> v(SIZE);
    std::iota(v.begin(), v.end(), 0);
    std::shuffle(v.begin(), v.end(), std::mt19937(5489u));
    using namespace boost::chrono;
    auto start = high_resolution_clock::now();
    BubbleSort(v.data(), v.size());
    auto finish = high_resolution_clock::now();
    std::printf("%ld  msn", duration_cast<milliseconds>(finish-start).count());
}

我用(clan)g++ -O3 -std=c++11 sort.cpp -lboost_system -lboost_chrono -lrt编译.

所以,问题一定出在别的地方。