Python打印计算结果比执行计算更耗时
我写了一个Python脚本,结果让我很惊讶。这个脚本基本上是接收五个20位的数字,把它们相乘,然后再把结果提高到3000的幂。为了测量计算所需的时间,我用了一个叫timeit的模块。当我运行这个脚本时,它显示计算只花了3*10^-7秒。
import timeit
outputFile = open("output.txt", "w")
start = timeit.default_timer()
x = (87459837581209463928*23745987364728194857*27385647593847564738*10293769154925693856*12345678901234567891)**3000
stop = timeit.default_timer()
time = stop-start
print "Time taken for the calculation was {} seconds".format(time)
outputFile.writelines(str(x))
outputFile.close()
y = raw_input("Press enter to exit.")
然后它生成了一个文件,叫output.txt,但这个脚本在大约15秒后才结束。
这是不是意味着打印一个280KB的文件所花的时间比计算的时间还要长呢?我觉得不太可能。
如果不是这样,那是不是说Python在调用变量x的时候才会执行计算?每次计算这个变量的时候都会执行计算,还是说它会把实际的值存储在变量里呢?
我刚写了另一个脚本,确认Python写结果到.txt文件大约需要0.03秒。那么,为什么Python会在后面才执行计算呢?
3 个回答
把数字转换成字符串的过程花了很长时间:
In [68]: %time x = (87459837581209463928*23745987364728194857*27385647593847564738*10293769154925693856*12345678901234567891)**3000
CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
Wall time: 0.00 s
In [69]: %time xs = str(x)
CPU times: user 1.98 s, sys: 0.00 s, total: 1.98 s
Wall time: 1.98 s
In [71]: %time print xs
CPU times: user 0.01 s, sys: 0.00 s, total: 0.01 s
Wall time: 0.04 s
不过,对于有数十万位数字的情况,这也不算意外。
编辑
和其他回答不同,写入文件其实并没有那么耗时:
In [72]: %time with open('tmp.file', 'w') as f: f.write(xs)
CPU times: user 0.00 s, sys: 0.01 s, total: 0.01 s
Wall time: 0.00 s
除了其他的回答,建议你用 outputFile.write(str(x))
来代替 writelines
。因为 writelines
是用来处理一系列字符串的。在你的情况中,它会逐个字符地写入字符串。经过简单测试,发现 writelines
的速度慢了 3.7 倍:
>>> timeit("f.writelines(str(s))", setup="f=open('tmp.txt','w');s=range(1000)", number=10000)
4.935087700632465
>>> timeit("f.write(str(s))", setup="f=open('tmp.txt','w');s=range(1000)", number=10000)
1.3468097837871085
问题不在于计算本身,也不是写文件的问题,而是把结果从内部的二进制格式转换成十进制格式时,花费了大量时间。这个转换的时间与位数的平方成正比,而你这里的位数非常多。
如果你把输出的代码改成:
outputFile.writelines(hex(x))
你会发现运行速度快很多。因为转换成十六进制格式只需要的时间与位数成线性关系。
如果你真的需要以十进制格式输出超大的整数,可以考虑使用 decimal
模块。这个模块内部的计算是基于十进制的,然后转换成十进制字符串的时间与十进制数字的位数成线性关系。不过,你需要提前设置好十进制的精度,以免在四舍五入时丢失低位数字。