6

我用python写了一个脚本,这让我很惊讶。基本上,它需要五个 20 位数字,将它们相乘,然后将它们提高到 3000 的幂。timeit 模块用于查找计算计算所需的时间。好吧,当我运行这个脚本时,它说计算它需要 3*10^-7 秒。然后它会生成一个文件 output.txt,但脚本直到大约 15 秒后才结束。

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.")

这是否意味着打印一个 280kb 的文件实际上比执行计算需要更长的时间?(我觉得不太可能。)

如果不是这样,那么当调用变量 x 时,python 是否执行计算?它会在每次计算变量时执行计算,还是将实际值存储在变量中?

我刚刚编写了另一个脚本,它确认 python 将结果写入 .txt 文件需要 0.03 秒。那么,为什么 python 稍后再执行计算呢?

4

3 回答 3

11

问题不是计算,也不是写入文件:将结果从其内部二进制表示形式转换为 base-10 表示形式消耗了大量时间。这需要比特数的二次方时间,而且这里有很多比特。

如果您将输出行替换为:

outputFile.writelines(hex(x))

你会看到它运行得非常快。转换为十六进制表示只需要与位数成线性关系的时间。

如果你真的需要输出以 10 为基数的巨型整数,请考虑使用该decimal模块。这在内部以与基数 10 相关的表示形式进行计算,然后转换为十进制字符串需要与十进制位数成线性关系的时间。但是,您需要提前将小数上下文的精度设置为“足够大”的值,以避免丢失低位数字以进行舍入。

于 2014-03-30T18:36:01.617 回答
1

转换为字符串需要很长时间:

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
于 2014-03-30T18:11:15.660 回答
1

除了其他答案,使用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
于 2014-03-30T20:15:54.417 回答