魔法の呪文 @njit |     ✤ We Love Softbrain ✤ 

    ✤ We Love Softbrain ✤ 

        日々の仕事や、プライベートな趣味まで掲載しています。

こんにちは、シニアTですクローバー
 
今回は、pythonの高速化(numba)の続きですビックリマーク
いつのまにか、内包表記や高階関数ほか、かなり普通のプログラムに対応できてました。
なんの宣言もなしに、タプルを返すこともできます。
例えば、
 
from numba import njit
import numpy as np
import matplotlib.pyplot as plt
@njit
def myfunc(x, y):
    return (x * x + y * y < 1.0)
@njit
def mytest(X, Y, f):
    xy = np.array([(x, y) for x,y in zip(X, Y) if f(x, y)])
    return len(xy) * 4.0 / len(X), xy
n = 1000000
X = np.random.rand(n)
Y = np.random.rand(n)
a, xy = mytest(X, Y, myfunc)
plt.scatter(xy[:,0], xy[:,1])
plt.title("pi ≒ %4.2f" % a)
plt.show()
 
プログラムの出来栄えはさておき(苦笑)、ぱっとみ普通のpythonだと僕は思います。
これを実行すると、πの近似値などが表示され、動いてることが分かりますビックリマーク
前回紹介した、%timeitを使うと、@njitあるなしで、mytestの時間が20倍くらい違うこともわかります。
っていうか@njitを外すと、結果を待つのが苦痛になりますガーン
 
これはもはや、「@njitは魔法の呪文」と言って、違和感ないのかもビックリマーク
とはいえ、関数を返すタイプの高階関数

def adder(x):
   _x = x
  def adr(a):
     nonlocal _x
     _x += a
    return _x
  return adr

は、動かせませんでした。
adrをjitがコンパイルするにはaの値が必要だから、adderが呼ばれたときに、adrを返せというのは、無茶かもしれません。
制約はあるにせよ、@njitを付けるだけで、多くの末端の小さな関数が速く動くというのは、ありがたいです音譜
なお、内包表記は、上記の通りnp.array()でくるんだほうが、高速ですビックリマーク
コンパイラが、リストを作る作業を、省いちゃうんでしょう。
 
添付は、過去の悪事の写真。手前の茶色のカタマリは、豚足ですクローバー
最初にタンシタとビール大瓶頼んで、それから....てへぺろ