- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我写了一个简单的埃拉托色尼筛法,它使用一个 1 列表,如果不是素数,则将它们变成零,如下所示:
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]]
我用 %timeit
测试了它的运行速度并得到:
#n: t
#10**1: 7 μs
#10**2: 26.6 μs
#10**3: 234 μs
#10**4: 2.46 ms
#10**5: 26.4 ms
#10**6: 292 ms
#10**7: 3.27 s
我假设,如果我将 [1]
和 0
更改为 boolean 值,它会运行得更快......但它恰恰相反:
#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
为什么 boolean 值比较慢?
最佳答案
发生这种情况是因为 True
和 False
在 Python 2 中被查找为全局变量。0
和 1
文字只是常量,通过快速数组引用查找,而全局变量是全局命名空间中的字典查找(落入内置命名空间):
>>> import dis
>>> def foo():
... a = True
... b = 1
...
>>> dis.dis(foo)
2 0 LOAD_GLOBAL 0 (True)
3 STORE_FAST 0 (a)
3 6 LOAD_CONST 1 (1)
9 STORE_FAST 1 (b)
12 LOAD_CONST 0 (None)
15 RETURN_VALUE
True
值使用 LOAD_GLOBAL
字节码查找,而 1
字面值使用 LOAD_CONST 复制到堆栈
。
如果你使 True
和 False
locals 你可以让它们再次变得同样快:
def eSieve(n, True=True, False=False):
m = [True]*(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]=False
return [i for i in xrange(2,n) if m[i]]
将 True
和 False
作为参数的默认值分配给函数这些名称作为局部变量,具有完全相同的值;再次使用简化版本:
>>> def bar(True=True, False=False):
... True == False
...
>>> dis.dis(bar)
2 0 LOAD_FAST 0 (True)
3 LOAD_FAST 1 (False)
6 COMPARE_OP 2 (==)
9 POP_TOP
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
注意 LOAD_FAST
操作码,现在与 LOAD_CONST
字节码一样具有索引; CPython 函数中的局部变量就像字节码常量一样存储在数组中。
随着这一变化,使用 boolean 值胜出,尽管优势很小;我的时间:
# n integers globals locals
# 10**1 4.31 µs 4.2 µs 4.2 µs
# 10**2 17.1 µs 17.3 µs 16.5 µs
# 10**3 147 µs 158 µs 144 µs
# 10**4 1.5 ms 1.66 ms 1.48 ms
# 10**5 16.4 ms 18.2 ms 15.9 ms
# 10**6 190 ms 215 ms 189 ms
# 10**7 2.21 s 2.47 s 2.18 s
区别并没有那么大,因为 Python boolean 值只是一个 int
子类。
请注意,在 Python 3 中,True
和 False
已成为关键字并且不能再分配给它们,从而可以像整数文字一样对待它们。
关于python - 为什么我的埃拉托色尼筛法处理整数比处理 boolean 值更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31459623/
[上下文:java 8,spring boot 1.5.1] 我们正在创建一个 RESTful 服务,我们需要能够上传大文件。我想要的是一个看起来像这样的 api @RequestLine("POST
我是一名优秀的程序员,十分优秀!