Ускорение Numba на вложенных функциях - PullRequest
0 голосов
/ 12 февраля 2019

Я пытался использовать numba для ускорения лямбда-функции , но мне не удалось это сделать.Похоже, лямбда не поддерживается numba.Поэтому я переписал лямбда-функцию как функцию 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, если я оцениваю ее.Так что никакого ускорения вообще нет ... Я ищу способ ускорить всю функцию оболочки.Если у кого есть идеи, пожалуйста, помогите.Спасибо!

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019

Это не только компиляция, но и отправка функции "jinted".

Не стоит использовать numba jit для такой простой функции только со скалярными компонентами.Если бы аргументы были массивами данных и операция должна была выполняться векторным способом, это имело бы смысл ... но только тогда, когда число элементов растет.

В numba у вас есть две накладные расходы: 1.Компиляция 2. Диспетчеризация (данная функция может иметь разные скомпилированные версии в зависимости от типов аргументов, поэтому необходимо выполнить сигнатуру типа для вызова, выполнить проверку внутреннего словаря на основе этой сигнатуры, аргументы распакованыи фактический звонок сделан).Это занимает немалое количество времени.Таким образом, вам нужна функция, которая достаточно сложна, чтобы амортизировать это время

Правило большого пальца: она не будет работать для тривиального кода, который не имеет цикла, либо явного (для, в то время как ...), либо неявного (векторный код лучше)обрабатывается через @numba.vectorize).

0 голосов
/ 12 февраля 2019

Вы можете попытаться использовать кеш, чтобы избежать перекомпиляции при каждом вызове функции

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

Надеюсь, это поможет

...