我写了一个简单的Eratosthenes筛,它使用一个1的列表,如果不是质数,就把它们变成0,就像这样:
def eSieve(n): #Where m is fixed-length list of all integers up to n
'''Creates a list of primes less than or equal to n'''
m = [1]*(n+1)
for i in xrange(2,int((n)**0.5)+1):
if m[i]:
for j in xrange(i*i,n+1,i):
m[j]=0
return [i for i in xrange(2,n) if m[i]]
我测试了它的速度,得到:
^{pr2}$我假设,如果我把[1]
和0
改成布尔函数,它会运行得更快。。。但事实恰恰相反:
#n: t
#10**1: 7.31 μs
#10**2: 29.5 μs
#10**3: 297 μs
#10**4: 2.99 ms
#10**5: 29.9 ms
#10**6: 331 ms
#10**7: 3.7 s
为什么布尔人变慢了?在
发生这种情况是因为在Python2中,}是作为全局变量查找的。
True
和{0
和1
文本只是常量,通过快速数组引用查找,而全局变量则是全局命名空间中的字典查找(通过内置命名空间):使用
LOAD_GLOBAL
字节码查找True
值,而使用1
字节码将1
文本值复制到堆栈中。在如果您生成
^{pr2}$True
和False
局部变量,则可以同样快速地使它们:将
True
和False
指定为for参数的默认值,使函数将这些名称作为局部变量,具有完全相同的值;同样使用简化版本:注意
LOAD_FAST
操作码,现在的索引与LOAD_CONST
字节码相同;CPython函数中的局部变量与字节码常量一样存储在数组中。在有了这种变化,使用布尔函数会胜出,尽管差距很小;我的时间安排:
差别并不是很大,因为Python布尔函数只是一个
int
子类。在请注意,在python3中,}已经成为关键字,不能再赋值给它们,因此可以像对待整数文本一样对待它们。在
True
和{相关问题 更多 >
编程相关推荐