max*_*max 8 python performance implementation closures python-3.x
当我替换这段代码时,我认为我提高了性能:
def f(a, b):
return math.sqrt(a) * b
result = []
a = 100
for b in range(1000000):
result.append(f(a, b))
Run Code Online (Sandbox Code Playgroud)
有:
def g(a):
def f(b):
return math.sqrt(a) * b
return f
result = []
a = 100
func = g(a)
for b in range(1000000):
result.append(func(b))
Run Code Online (Sandbox Code Playgroud)
我假设自从a在执行闭包时修复,解释器将预先计算所涉及的所有内容,a因此math.sqrt(a)将重复一次而不是1000000次.
根据实施情况,我的理解总是正确的,或总是不正确,或正确/不正确?
我注意到代码对象func是在运行时之前构建的(至少在CPython中),并且是不可变的.然后代码对象似乎使用全局环境来实现闭包.这似乎表明我希望的优化不会发生.
Nik*_* B. 13
我假设因为在执行闭包时a是固定的,解释器会预先计算涉及a的所有内容,因此math.sqrt(a)将重复一次而不是1000000次.
这个假设是错误的,我不知道它来自哪里.闭包只捕获变量绑定,在你的情况下它捕获值的值a,但这并不意味着还有更多的魔法:math.sqrt(a)每次f调用时表达式仍会被评估.
毕竟,它拥有所有的时间,因为解释器不知道被计算sqrt为"纯"(返回值仅取决于参数和执行没有副作用).像你期望的那样优化在函数式语言中是实用的(引用透明性和静态类型在这里有很多帮助),但在Python中很难实现,这是一种命令式和动态类型的语言.
也就是说,如果要预先计算其值math.sqrt(a),则需要明确地执行此操作:
def g(a):
s = math.sqrt(a)
def f(b):
return s * b
return f
Run Code Online (Sandbox Code Playgroud)
或使用lambda:
def g(a):
s = math.sqrt(a)
return lambda b: s * b
Run Code Online (Sandbox Code Playgroud)
现在g真的返回一个带有1个参数的函数,你必须只用一个参数调用结果.
| 归档时间: |
|
| 查看次数: |
1570 次 |
| 最近记录: |