Python的整数到字符串转换算法使用一个运行O(n**2)的简化算法。当数字的长度增加一倍时,转换时间将增加四倍。在
在我的电脑上进行的一些简单测试显示,运行时间增加了:$ time py35 -c "n=str(2**1000000)"
user 0m1.808s
$ time py35 -c "n=str(2**2000000)"
user 0m7.128s
$ time py35 -c "n=str(2**4000000)"
user 0m28.444s
$ time py35 -c "n=str(2**8000000)"
user 1m54.164s
因为实际的指数比我上次测试值大10倍,所以它应该要长100倍。或者仅仅3个多小时。在
能快点吗?对。有几种方法更快。在
方法1
将非常大的数除以10的幂可以更快地分成两个大小大致相等但更小的数。重复这个过程,直到数字相对较小。然后在每个数字上使用str(),并使用前导零将结果填充到与-10的最后一次幂相同的长度。然后将字符串连接起来形成最终结果。这个方法被mpmath库使用,文档表明它应该快3倍。在
方法2
Python的整数以二进制格式存储。二进制对于计算来说很好,但是二进制到十进制的转换是一个瓶颈。您可以定义自己的整数类型,将值存储在100位(或类似值)十进制数字的块中。运算(求幂、乘法、除法)会比较慢,但转换成字符串会非常快。在
很多年前,我实现了这样一个类,并使用了高效的乘法和除法算法。该代码在互联网上已不可用,但我确实找到了一个备份副本,我测试过。运行时间缩短到14秒左右。在
更新
如果使用Python的本机整数类型,在我的计算机上总运行时间不到14秒。如果使用gmpy2的整数类型,则运行时间为~3.5秒。在
^{pr2}$
方法3
我维护了gmpy2库,它提供了对GMP库的简单访问,以实现快速整数运算。GMP在高度优化的C和汇编代码中实现方法1,并在大约5秒内计算质数和字符串表示。在
方法4
Python中的decimal模块将值存储为十进制数字。python3的最新版本包括decimal库的C实现,它比python2的纯Python实现要快得多。在我的计算机上,C实现只需3秒多。在from decimal import *
getcontext().prec = 23000000
getcontext().Emin = -999999999
getcontext().Emax = 999999999
x=Decimal(2)**74207281 - 1
s=str(x)