4

値のリストを作成するために、次の for ループがあります。

p = 7
A = []

for i in range(0, 10**p):
    A.append(i**3 + i**2)

リストの作成を高速化するために、ベクトル化されたアプローチを使用してリストを Numpy 配列として作成しました。pこのアプローチは、特に範囲が拡大する大きな値の場合、同等の for ループよりもはるかに高速です。

import numpy as np
from numba import autojit

p = 7
m = np.arange(0, 10**p)
D = np.empty(len(m))
D = m**3 + m**2

配列の作成をさらに高速化するために、Numba パッケージを使用しようと考えました。以下は私の現在の試みです。

@autojit
def func(a):
    a = np.asarray(a)
    n = np.arange(0, 10**p)
    a = np.append(a, n**3 + n**2)
    return a

e = []
E = func(e)

残念ながら、Numba を使用した場合のパフォーマンスの向上は見られません。これは、Numpy のみを使用したベクトル化アプローチよりもほぼ 3 倍遅くなります。

これにNumbaを使用する方法に関する提案はありますか?

4

1 に答える 1

6

Numba は、任意のメソッド呼び出しを高速化しません。ライブラリを呼び出している場合、ほとんどの場合、numba は実際には何もできません。しかし、少し違う方法で書き直しても、かなりのスピードアップを得ることができます (私は numba 0.14.0 を使用しています。別のバージョンやハードウェアなどを使用している場合、特に numba が活発に開発中です):

import numpy as np
import numba as nb

def func(a, p):
    a = np.asarray(a)
    n = np.arange(0, 10**p)
    a = np.append(a, n**3 + n**2)
    return a

@nb.jit
def func2(a, p):
    a = np.asarray(a)
    n = np.empty(10**p, dtype=np.float64)
    for k in range(10**p):
        n[k] = k*k*(k + 1)

    return np.append(a, n)

p = 6
e = []
E = func(e, p)
E2 = func2(e, p)
print np.allclose(E, E2)

そしてタイミング:

In [51]:

%timeit func(e, p)
10 loops, best of 3: 42.9 ms per loop
In [52]:

%timeit func2(e, p)
100 loops, best of 3: 3.09 ms per loop

また、p=7数値の精度についても少し注意する必要があります。

numba の鍵は、ループをアンロールし、numba がサポートする「プリミティブ」算術呼び出しのみを行うことです。

于 2014-10-14T20:29:19.740 に答える