Cha*_*net 49 python optimization inline-functions
我刚刚意识到这一点
x.real*x.real+x.imag*x.imag
Run Code Online (Sandbox Code Playgroud)
比做的快三倍
abs(x)**2
Run Code Online (Sandbox Code Playgroud)
其中x是一个复数的numpy数组.为了代码可读性,我可以定义一个类似的函数
def abs2(x):
return x.real*x.real+x.imag*x.imag
Run Code Online (Sandbox Code Playgroud)
它仍然比abs(x)**2快得多,但它是以函数调用为代价的.是否可以内联这样的函数,就像在C中使用宏或使用内联关键字一样?
小智 34
是否可以内联这样的函数,就像在C中使用宏或使用内联关键字一样?
在达到这个特定指令之前,Python解释器甚至不知道是否存在这样的功能,更不用说它的功能了.
正如评论中所指出的,PyPy 将自动内联(上面仍然保持 - 它"简单地"在运行时生成优化版本,从中受益,但在它失效时突破它),尽管在这种特殊情况下无效因为在PyPy上实现NumPy很快就开始了,直到今天还没有beta级别.但最重要的是:不要担心Python中这个级别的优化.要么实现自己优化它们,要么它们不优化它,这不是你的责任.
AXO*_*AXO 14
不完全是OP所要求的,但是关闭:
Inliner内联Python函数调用.此博客文章的概念证明
Run Code Online (Sandbox Code Playgroud)from inliner import inline @inline def add_stuff(x, y): return x + y def add_lots_of_numbers(): results = [] for i in xrange(10): results.append(add_stuff(i, i+1))在上面的代码中,add_lots_of_numbers函数被转换为:
Run Code Online (Sandbox Code Playgroud)def add_lots_of_numbers(): results = [] for i in xrange(10): results.append(i + i + 1)
任何对这个问题感兴趣的人以及在CPython中实现这样的优化器所涉及的复杂性,也可能想看看:
我同意其他人的看法,这样的优化只会让你对CPython感到痛苦,如果你关心性能,你应该考虑PyPy(虽然我们的NumPy可能太不完整而无用).但是我不同意并且说你可以关心PyPy上的这种优化,而不是特别说明PyPy会自动执行此操作,但是如果你很了解PyPy,你真的可以调整你的代码以使PyPy发出你想要的程序集,不是你几乎需要的.
没有.
最接近C宏的是一个脚本(awk或其他),你可以包含在一个makefile中,它用你的python脚本中的abs(x)**2替换某个模式.
实际上,它的计算可能甚至更快,例如:
x.real** 2+ x.imag** 2
Run Code Online (Sandbox Code Playgroud)
因此,函数调用的额外成本可能会减少。让我们来看看:
In []: n= 1e4
In []: x= randn(n, 1)+ 1j* rand(n, 1)
In []: %timeit x.real* x.real+ x.imag* x.imag
10000 loops, best of 3: 100 us per loop
In []: %timeit x.real** 2+ x.imag** 2
10000 loops, best of 3: 77.9 us per loop
Run Code Online (Sandbox Code Playgroud)
并将计算封装在一个函数中:
In []: def abs2(x):
..: return x.real** 2+ x.imag** 2
..:
In []: %timeit abs2(x)
10000 loops, best of 3: 80.1 us per loop
Run Code Online (Sandbox Code Playgroud)
无论如何(如其他人所指出的那样),这种微优化(以避免函数调用)并不是真正有效的编写python代码的方法。
| 归档时间: |
|
| 查看次数: |
42636 次 |
| 最近记录: |