如何判断在迭代中放置两个额外的赋值是否昂贵,或者设置if条件来测试另一个东西?在这里我详细说明。问题是生成并打印斐波纳契数列的前n个项,其中n> = 1。我在C中的工具是:
#include<stdio.h>
void main()
{
int x=0,y=1,output=0,l,n;
printf("Enter the number of terms you need of Fibonacci Sequence ? ");
scanf("%d",&n);
printf("\n");
for (l=1;l<=n;l++)
{
output=output+x;
x=y;
y=output;
printf("%d ",output);
}
}
但是“如何通过计算机解决它”这本书的作者说这是低效的,因为它对生成的单个斐波那契数使用了两个额外的分配。他建议:
a=0
b=1
loop:
print a,b
a=a+b
b=a+b
我同意这更有效率,因为它始终保持a和b相关,并且一个分配产生一个数字。但它一次打印或提供两个斐波那契数字。假设问题是生成奇数个术语,我们会做什么?作者建议设置一个测试条件来检查n是否为奇数。通过在每次迭代中添加if测试,我们不会失去减少分配数量的收益吗?
答案 0 :(得分:5)
我认为作者的建议非常糟糕,甚至在一本针对初级程序员的书中提出这一建议。 (编辑:公平地说,这本书最初发表于1982年,当时编程通常比现在低得多。)
99.9%的代码不需要优化。特别是在像这样的代码中,将非常便宜的操作(整数运算)和非常昂贵的操作(I / O)混合在一起,优化廉价部件完全浪费时间。
只有当需要从硬件中挤出所有性能时,才应在时间要求严格的代码中考虑这样的微优化。
当您确实需要时,了解哪些选项效果最佳的唯一方法是度量。即使这样,结果也可能因不同的处理器,平台,内存配置而发生变化......
答案 1 :(得分:3)
不评论您的实际代码:在学习编程时,请记住,使代码难以阅读的次要效率提升并不值得。至少,直到生产应用程序的分析显示它是值得的。
编写人类可以阅读的代码;它会让你的生活更轻松,让维护程序员不要诅咒你和你后代的名字。
答案 2 :(得分:2)
我的第一个建议与其他建议相呼应:首先争取干净,清晰的代码,然后优化您知道存在性能问题的位置。 (很难想象一个对时间要求严格的斐波那契音序器......)
然而,作为在微秒很重要的系统上工作的人来说,对于你提出的问题有一个简单的解决方案:“if odd”测试只进行一次,而不是在循环内。
循环展开的一般模式是
create X repetitions of the loop logic.
divide N by X.
execute the loop N/X times.
handle the N%X remaining items.
针对您的具体情况:
a=0;
b=1;
nLoops = n/2;
while (nloops-- > 0) {
print a,b;
a=a+b;
b=a+b;
}
if (isOdd(n)) {
print a;
}
(另请注意,N / 2和isOdd在二进制计算机上非常快速且非常快。)