繁体   English   中英

Python 等价于内联函数或宏

[英]Python equivalence to inline functions or macros

我才意识到做

x.real*x.real+x.imag*x.imag

比做的快三倍

abs(x)**2

其中 x 是一个 numpy 复数数组。 为了代码可读性,我可以定义一个函数,如

def abs2(x):
    return x.real*x.real+x.imag*x.imag

这仍然比 abs(x)**2 快得多,但它是以函数调用为代价的。 是否可以内联这样的函数,就像我在 C 中使用宏或使用 inline 关键字所做的那样?

是否可以内联这样的函数,就像我在 C 中使用宏或使用 inline 关键字所做的那样?

不。在到达这个特定指令之前,Python 解释器甚至不知道是否有这样的函数,更不用说它做了什么。

正如评论中所指出的,PyPy将自动内联(以上仍然成立 - 它“简单地”在运行时生成一个优化版本,从中受益,但在它失效时脱离它),尽管在这种特定情况下没有帮助因为在 PyPy 上实施 NumPy 是在不久前才开始的,直到今天还不是 beta 级别。 但最重要的是:不要担心 Python 中这个级别的优化。 实现要么自己优化,要么不优化,这不是你的责任。

不完全是 OP 所要求的,但关闭:

Inliner 内联 Python 函数调用。 这篇博文的概念证明

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 函数被转换成这样:

 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

因此,函数调用的额外成本可能会减少。 让我们来看看:

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

并将计算封装在一个函数中:

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

无论如何(正如其他人指出的那样)这种微优化(为了避免函数调用)并不是编写 python 代码的真正有效的方式。

您可以尝试使用lambda

abs2 = lambda x : x.real*x.real+x.imag*x.imag

然后通过以下方式调用它:

y = abs2(x)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM