如何以及为什么这段代码比我的更快?

时间:2016-10-06 20:35:20

标签: c++

我是竞争性编码(C ++)的新手,并且正在实施基于实施的hackerEarth问题。我提交了一个问题来查找3 diff中数组的求和。部分 。 这是我的代码执行1.010039s:

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

我们可以看到,在第二种情况下,循环还有更多,但为什么它更快?

2 个答案:

答案 0 :(得分:0)

只要它们不重叠,你写的循环数并不重要。
使第二个算法更快的真正因素是每次索引i移动3次而不是第一个算法(逐步),你也可以考虑if s正如您所知,在竞争性节目中每毫秒计数的巨大数据输入的变化 因为我会建议你学习复杂性,这将有助于你对我的竞争激情。

答案 1 :(得分:0)

最少时间的代码是非分支的(循环条件除外)。这意味着编译器确切地知道将会发生什么,将执行哪个指令。这也意味着CPU知道即将到来的指令以及将执行的指令。这样就可以由编译器生成最佳指令,并允许CPU提取合适的内存并为即将发生的事情做好准备。 结果,整个CPU大部分时间都得到了充分利用。

在您的情况下,无法预测i%3的结果,因此CPU停顿了,因为它并不总是正确地计划ifs的哪个分支。实际上,您的代码对于缓存局部性更好,因为它只接触一次连续内存。但是,分支部分会带来更大的性能损失。

一般规则:代码中的if最少,则速度可能更快。