[英]comparing the time taken by mathematical operations
从理论上讲,哪个实施应该更快?
long int total=0;
for(int n=1;n<=200000;)`
{
total=total + n*(++n);
}
要么
long int total=0,sum=0;
for(int n=1;n<=200000;n++)`
{
sum =sum+2*n;
total=total + sum;
}
还是没有任何区别?
您需要做的是显式地编写要比较的两个程序。 我想我知道您的意思,但是如果您明确编写它,它将是确定的。
假设我对您的意思是正确的,则渐进时间复杂度对该问题毫无意义,因为没有自由变量。 n
被“绑定”到循环中。 如果将200000
替换为M
那么谈论时间复杂度将是有意义的。
就绝对而言,您没有编写两个程序中哪个程序更快的问题也是一个框架欠佳的问题,因为答案很可能取决于上下文,正如Mark Dickinson所指出的那样。 如果我对程序的外观是正确的,那么算术运算的次数似乎大致相同。 这可能意味着程序将在大约相同的时间内运行,也可能不会。 我的猜测是时差不会被察觉,但是为什么不尝试一下呢?
最后,如果您要使用捷径2(1)+2(2)+...+2(n)=n(n+1)
,那为什么不走得更远一点呢?削减1(2)+2(3)+...+n(n+1)
的总和? 我们有
n(n+1) = (1/3)((n+1)^3 - n^3) - (1/3)
所以
1(2)+2(3)+...+n(n+1)
= (1/3)(2^3-1^3) - (1/3) + (1/3)(3^3-2^3) - (1/3) + ... + (1/3)((n+1)^3-n^3) - (1/3)
= ((n+1)^3 - n - 1)/3
该系列是“ telescoping”,因此中间的所有立方体项都将取消。 结果表达式可以用5个算术运算求值。
如果用上面的n = 200000代替,您将看到int total
对于32位int
类型将溢出。 那是你的意图吗?
更新
我在系统(MacBook Air / Yosemite)上尝试过。 我比较的程序是
#include <stdio.h>
int main() {
long int total;
for (int trial=0; trial<1000; ++trial) {
total = 0;
for (int i=1; i<=200000; ++i) {
total = total + i*(i+1);
}
}
printf("answer is %ld", total);
return 0;
}
和
#include <stdio.h>
int main() {
long int total;
int sum;
for (int trial=0; trial<1000; ++trial) {
total = 0;
sum = 0;
for (int i=1; i<=200000; ++i) {
sum = sum + 2*i;
total = total + sum;
}
}
printf("answer is %ld", total);
return 0;
}
我用gcc -O
编译了它们,然后在unix time
命令下运行它们。 显而易见的赢家(在我的系统上,以其特定的体系结构以及我做出的选择)是第一个程序。 大约需要160毫秒,而第二秒大约需要240毫秒。 第一个运行时间为第二个时间的2/3。 我对架构了解不足,无法推测出差异的原因。
请注意,程序中的行total = total + i*(i++);
是不正确的。 计算出i*i
然后增加i
。 此外,该行和改进的total = total + i*(++i)
生成警告。
一些风格上的问题:对于循环索引,我使用i
而不是n
,因此人们不会对n
含义感到困惑。 我习惯性地使用++x
来增加x而不是x++
,这可能会使旧的x
成为不必要的临时副本。
好吧,如果您从算法的角度讲,那么第一个操作的复杂度会高于第二个操作。 第一次操作的复杂度为O(1),而在第二种情况下,复杂度为O(n)。 因此,当您增加输入的数量时,第一个输入所花的时间可能会少于第二个输入所花的时间。 延迟与执行操作所需的机器指令成正比。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.