如何以及为什么这个代码比我的快
How and Why This code is Faster than mine?
我是竞争编码(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越少,速度越快。
相关文章:
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 我的字符计数代码计算错误.为什么
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 为什么我的代码在输出中增加了93天
- 我的简单if-else语句是如何无法访问的代码
- 0-1背包代码中的错误.我的代码中有什么错误
- 我的代码中有错误吗?使用BGI图形的C++代码对我不起作用
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 尝试链接我的着色器时,我收到错误代码"error c5145 must write to gl_position"
- 在我的代码中,获得最大的Pair Wise产品C++和输出并不总是正确的
- 代码在我的计算机上运行良好,但是在将其提交给coursera时遇到未知的信号11问题
- 为什么我需要C++中不同的排序格式来对这个USACO代码上的数组和优先级队列进行排序
- 为什么我的C++代码中出现'Segmentation Fault: 11'行?
- 是否值得降低我的代码的可读性,以便在出现内存不足错误时提供异常安全性?
- 为什么我的C++程序的程序集输出充满了 .ascii,没有汇编代码?
- 无法在我的堆排序代码中找到错误.无法正确执行.C++
- 如何重写全局方法名称以在调用原始方法之前将我的代码推到前面
- 为什么我的 BaseClass:Method 代码编译(带有单冒号)?
- 我的代码运行良好,但在游戏循环中中断
- 8谜题代码.我的队列没有填充,我找不到错误的位置