前言
在讨论亲密数程序的加速博客中(传送门),里面加速的根本原因,是求因子和的子函数中,用range(math.sqrt(num))
代替range(num//2 +1)
,后来在看到其他人博客中的实现(C语言),他们用
j
∗
j
≤
n
u
m
j*j \le num
j∗j≤num来代替求根号,理由是,引进一个外部函数,会拖慢程序的运行速度。由于Python中的For函数,语法跟C的很不同,没法直接实现这个构想。于是,这一篇,我用While循环语句实现求因子和的子函数,结果出乎意料……这一篇因此探讨Python中 while 循环 和 for 循环,二者的运行效率竟然不一样!同时,我会把之前一些遗漏的知识点补齐。
While 循环实现的因子和程序
def GetSumFactorFaster3(num):
factorSum = 1
j = 2 # 因子测试从2开始
while j*j < num:
if num % j == 0: # 确定为因子
factorSum += j + num // j
j += 1
if j*j == num: # 取j**2 会比 j*j慢很多
factorSum += j
return factorSum
运行效果
很尴尬的是,在上一篇用for循环实现,只需要0.14秒,如下图
进一步尝试, j*j 换成 j**2
def GetSumFactorFaster3(num):
factorSum = 1
j = 2 # 因子测试从2开始
while j**2 < num:
if num % j == 0: # 确定为因子
factorSum += j + num // j
j += 1
if j**2 == num: # 取j**2 会比 j*j慢很多
factorSum += j
return factorSum
运行效果
运行结果更加令人大跌眼镜……从仅需0.26s
→
\rarr
→ 0.82s。
总结
基于上面的测试,可以得出下面四条Python的使用小技巧
- Python 中,For 循环运行速度比 While 快,因为For循环只迭代一个序列里面的对象,不需要任何判断;在程序中,判断语句是会影响程序运行速度的,因此,减少判断语句,是程序提速的关键。
- Python中, j ∗ j j * j j∗j运行比 j ∗ ∗ 2 j**2 j∗∗2快
- 在Python中,
import math
这些内置模块,对程序性能影响不大,小于使用判断语句,在使用while语句的时候,用了3个判断 for i in range(num // 2 +1): if num // j > j,
不等于range(math.sqrt(num))
,因为前者的遍历次数并没有减少,而这个遍历次数,正是造成程序慢的罪魁祸首,可想而知,用第一个语句,程序只会更慢(我不会告诉你,第一个语句正是我一开始想当然的结果,以为能加速,结果程序更慢了……)