为何含while循环的LCM计算程序比取模实现性能更优?
为什么程序1计算最小公倍数(LCM)的性能优于程序2?
首先要明确一个关键问题:程序2的逻辑是残缺且错误的——它只能正确计算「其中一个数是另一个数的整数倍」场景下的LCM,其他所有非倍数关系的输入,都会输出错误结果。比如输入15和9,程序2会因15%9≠0直接将GCD(最大公约数)设为1,算出错误的LCM=135,而实际正确值是45。
接下来具体分析性能差异的核心原因:
1. 程序1的核心是正确的辗转相减法求GCD
程序1通过辗转相减法计算两个数的GCD,再用公式 LCM(a,b) = (a*b)/GCD(a,b) 得到结果,逻辑完全正确:
temp1 = firstNumber; temp2 = secondNumber; while (firstNumber != secondNumber) { if (firstNumber > secondNumber) { firstNumber -= secondNumber; } else { secondNumber -= firstNumber; } } lcm = (temp1 * temp2) / firstNumber;
以输入1513和3为例,循环执行的是几百次简单的减法和比较操作——这些都是CPU最基础的指令,执行周期极短,哪怕几百次循环,总耗时也微乎其微。
2. 程序2的取模运算开销远高于程序1的减法操作
程序2的核心判断依赖取模运算(%):
int f =1; if(firstNumber > secondNumber) { if( firstNumber%secondNumber == 0) f = secondNumber; } else{ if(secondNumber%firstNumber ==0) f = firstNumber; } lcm = (firstNumber*secondNumber)/f;
取模运算本质是除法的衍生操作,CPU执行除法/取模的周期远多于减法和比较。哪怕程序2只执行一次取模,其开销也可能超过程序1几百次减法循环的总开销。
3. 为什么差值大时程序1没变慢?
你担心差值大时循环次数多会拖慢性能,但实际情况是:
- 减法是CPU的原生快速指令,单次执行耗时可以忽略不计,几百次循环的总开销依然极低
- 程序2的取模运算本身就是高开销操作,哪怕只执行一次,也比程序1的循环更耗时
- 更关键的是,程序2根本无法处理大多数输入场景,所谓的「性能对比」是建立在程序2逻辑错误的基础上——它连正确结果都输出不了,谈性能没有实际意义,但单从执行开销看,程序1的简单循环操作也天然比程序2的取模操作高效。
内容的提问来源于stack exchange,提问作者Tanvi Khade
相关产品推荐
相关产品推荐

