简体   繁体   English

比较数学运算所花费的时间

[英]comparing the time taken by mathematical operations

Which implementation whould be faster (in theory)- 从理论上讲,哪个实施应该更快?

long int total=0;
for(int n=1;n<=200000;)`
{ 
  total=total + n*(++n);
}

or 要么

 long int total=0,sum=0;
for(int n=1;n<=200000;n++)`
{ 
  sum =sum+2*n;
  total=total + sum;
}

Or will there not be any difference? 还是没有任何区别?

What you need to do is write explicitly the two programs you want to compare. 您需要做的是显式地编写要比较的两个程序。 I think I know what you mean, but it would be definitive if you wrote it explicitly. 我想我知道您的意思,但是如果您明确编写它,它将是确定的。

Assuming my guess is right about what you mean, asymptotic time complexity makes no sense for this question, because there is no free variable. 假设我对您的意思是正确的,则渐进时间复杂度对该问题毫无意义,因为没有自由变量。 n is "bound" to the loop. n被“绑定”到循环中。 If you replaced 200000 with M then it would make some sense to talk about time complexity. 如果将200000替换为M那么谈论时间复杂度将是有意义的。

The question of which of the two programs that you didn't write is faster in absolute terms is also a poorly framed question, because the answer most likely depends on context, as Mark Dickinson has pointed out. 就绝对而言,您没有编写两个程序中哪个程序更快的问题也是一个框架欠佳的问题,因为答案很可能取决于上下文,正如Mark Dickinson所指出的那样。 If my guess is right about what the programs look like, then the number of arithmetic operations seems to be roughly the same. 如果我对程序的外观是正确的,那么算术运算的次数似乎大致相同。 That could mean the programs would run in about the same amount of time, or maybe not. 这可能意味着程序将在大约相同的时间内运行,也可能不会。 My guess is the time difference would be imperceptible, but why don't you just try it? 我的猜测是时差不会被察觉,但是为什么不尝试一下呢?

Finally, if you're going to use the short cut 2(1)+2(2)+...+2(n)=n(n+1) , then why don't you go further and use a short cut for the summation of 1(2)+2(3)+...+n(n+1) ? 最后,如果您要使用捷径2(1)+2(2)+...+2(n)=n(n+1) ,那为什么不走得更远一点呢?削减1(2)+2(3)+...+n(n+1)的总和? We have 我们有

n(n+1) = (1/3)((n+1)^3 - n^3) - (1/3)

so 所以

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

The series is "telescoping", so all the cubed terms in the middle cancel. 该系列是“ telescoping”,因此中间的所有立方体项都将取消。 The resulting expression can be evaluated in 5 arithmetic operations. 结果表达式可以用5个算术运算求值。

If you substitute n=200000 in the above, you'll see that int total will overflow for 32 bit int types. 如果用上面的n = 200000代替,您将看到int total对于32位int类型将溢出。 Is that your intent? 那是你的意图吗?

Update 更新

I tried it on my system (MacBook Air/Yosemite). 我在系统(MacBook Air / Yosemite)上尝试过。 The programs I compared are 我比较的程序是

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

and

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

I compiled both with gcc -O and then ran them under the unix time command. 我用gcc -O编译了它们,然后在unix time命令下运行它们。 The clear winner (on my system, with its particular architecture, and with the choices I made) is the first program. 显而易见的赢家(在我的系统上,以其特定的体系结构以及我做出的选择)是第一个程序。 It takes about 160 milliseconds, whereas the second takes about 240 milliseconds. 大约需要160毫秒,而第二秒大约需要240毫秒。 The first runs in 2/3 the time of the second. 第一个运行时间为第二个时间的2/3。 I don't know enough about the architecture to speculate on the reason for the difference. 我对架构了解不足,无法推测出差异的原因。

Note that the line in your program total = total + i*(i++); 请注意,程序中的行total = total + i*(i++); is incorrect. 是不正确的。 That calculates i*i then increments i . 计算出i*i然后增加i Furthermore, both that line and the improved total = total + i*(++i) generate a warning. 此外,该行和改进的total = total + i*(++i)生成警告。

A few stylistic issues: I use i rather than n for a loop index, so people don't get confused about what n means. 一些风格上的问题:对于循环索引,我使用i而不是n ,因此人们不会对n含义感到困惑。 I habitually use ++x to increment x rather than x++ which may make an unnecessary temporary copy of the old x . 我习惯性地使用++x来增加x而不是x++ ,这可能会使旧的x成为不必要的临时副本。

Well, if you are talking in terms of algorithm then complexity for first operation is higher than the second one. 好吧,如果您从算法的角度讲,那么第一个操作的复杂度会高于第二个操作。 Complexity for first operation is O(1) where as in second case it will be O(n). 第一次操作的复杂度为O(1),而在第二种情况下,复杂度为O(n)。 So when your number of inputs increases, then probably first one will take less time than second one. 因此,当您增加输入的数量时,第一个输入所花的时间可能会少于第二个输入所花的时间。 Delay is directly proportional to machine instructions required to execute the operation. 延迟与执行操作所需的机器指令成正比。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM