嵌套功能上的Numba加速

时间:2019-02-12 02:14:32

标签: python numba

我尝试使用numba来accelerate lambda function,但我没有这样做。似乎numba不支持lambda。因此,我将lambda函数重写为def函数。我正在构造一个隐式函数f(x,y,z)= x ^ 2 + y ^ 2-z ^ 2以及其他一些隐式函数,该隐式函数在构造后只会被评估一次。 xi,yi,zi用于隐式函数的翻译。

def wrapperNode(xi,yi,zi,R):

    @nb.jit(nopython=True)
    def Node(x,y,z):
        x = xi - x
        y = yi - y
        z = zi - z
        return x**2 + y**2 - z**2

    return Node

import time
for i in range(10):
    Start = time.time()
    Node = wrapperNode(i+1.0,i+2.0,i+3.0,i+4.0)
    a = Node(1.0,2.0,3.0)
    Final = time.time()
    print(Final-Start)

每个循环的时间结果:

0.137923002243042
0.14062094688415527
0.14144468307495117
0.1332840919494629
0.12716078758239746
0.14055514335632324
0.14062023162841797
0.1423487663269043
0.14061713218688965
0.1943662166595459

实际上,这比简单地评估包装函数中的Node函数要慢得多。每次更改包装函数的输入参数时,如果我对其求值,则计算机必须编译Node函数。所以根本没有加速...我正在寻找一种加速整个包装器功能的方法。如果有人有任何想法,请帮助。谢谢!

2 个答案:

答案 0 :(得分:1)

这不仅是编译,还是“ jitted”功能的分派。

对于仅具有标量组件的简单功能,不值得使用numba jit。如果参数是数据数组,并且要以矢量方式执行操作,那将是有道理的……但仅当元素数量增加时。

在numba中,您有两个开销: 1.编译 2.调度(给定的函数可能根据参数的类型而具有不同的编译版本,因此必须完成调用的类型签名,根据该签名对内部字典进行检查,将参数拆箱并实际的通话已完成)。这花费了不可忽略的时间。因此,您需要一个足够复杂的函数来分摊这次费用

经验法则:它不适用于无循环的普通代码,无论是显式的(for,while ...)还是隐式的(通过@ numba.vectorize更好地处理矢量代码)。

答案 1 :(得分:0)

您可以尝试使用缓存来避免在每次调用该函数时重新编译

@nb.jit(nopython=True,cache=True)

希望有帮助