如何以及为什么这个代码比我的快

How and Why This code is Faster than mine?

本文关键字:代码 我的 为什么      更新时间:2023-10-16

我是竞争编码(c++)的新手,并在基于实现的hackerEarth问题上进行实践。我提交了一个问题,求一个数组的3个不同部分的和。下面是我的代码,执行时间为1.010039秒:

int main()
{
    long unsigned int n, a[100000], s1 = 0, s2 = 0, s3 = 0;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        if (i % 3 == 0)
            s3 = s3 + a[i];
        else if ((i - 2) % 3 == 0)
            s2 = s2 + a[i];
        else
            s1 = s1 + a[i];
    }
    cout << s1 << " " << s2 << " " << s3;
    return 0;
}

这是最短时间代码:

int main()
{
    int n;
    long unsigned int a[100000];
    long unsigned int s1 = 0, s2 = 0, s3 = 0;
    int i;
    cin >> n;
    for (i = 0; i < n; i++) {
        cin >> a[i];
    }
    for (i = 0; i < n; i = i + 3) {
        s1 = s1 + a[i];
    }
    for (i = 1; i < n; i = i + 3) {
        s2 = s2 + a[i];
    }
    for (i = 2; i < n; i = i + 3) {
        s3 = s3 + a[i];
    }
    cout << s1 << " " << s2 << " " << s3 << endl;
    return 0;
}

我们可以看到,在第二种情况下有更多的for循环,但仍然更快,为什么呢?

不管你写了多少个循环,只要它们不重叠就行。
使第二种算法更快的真正因素是,在每一次索引i移动3次,不像第一个算法(一步一步),你也可以考虑if s,它将在巨大的数据输入中做出一点改变,你知道在竞争性编程中,每毫秒都很重要。
因此,我建议你学习复杂性,这将有助于你培养竞争热情,就像它对我一样。

时间最少的代码是非分支的(除了循环条件)。这意味着编译器确切地知道将要发生什么,哪条指令将被执行。这也意味着CPU知道即将到来的指令和将要执行的指令。这允许编译器生成最佳指令,并允许CPU获取正确的内存并为即将到来的内容做好准备。因此,大部分时间,整个CPU被充分利用。

在您的例子中,i%3的结果是无法预测的,所以CPU停止运行,因为它并不总是正确地计划它将使用哪个if分支。实际上,您的代码更适合缓存局部性,因为它只接触一次连续内存。但是分支部分对性能的影响要大得多。

作为一般规则:代码中if越少,速度越快。

相关文章: