雑記帳

ソフトを中心に雑記を書いてる割とすぐ転職したい人。コメント貰えると私が喜びます。

Pythonのコードを高速化(はじめてのNumba)

大昔の記事を書き足してなんとかしたいなぁと思いつつ、いつまでも更新出来ずにいました。
少し諦めてもう少し最近のことを書くことにしました。

背景

最近仕事でPythonのコードでツールを作って間に合わせることが増えたけれど、
実行時間が遅くてコマリンスなことになることもあったので、高速化のアプローチをしてみましたとさ。

最近はこんな本を読んでます。

Cython ―Cとの融合によるPythonの高速化

Cython ―Cとの融合によるPythonの高速化

英語kindle版がとてもとても安かったので買ってしまいました。

で、Pythonでは下のように色々な高速化手法が色々あるけど、さてどんな感じかなと。

  • Numpy
  • MultiProcessing
  • Cython
  • C拡張
  • Numba
  • ???

紹介した本と関係なしに、今回は聞いたこともなかったNumba様を使ってみます。

 やってみよう!

本サイトはこちら。 解説本とかは探したけど見つかりませんでした。

Numba — Numba

時間測定方法

ipythonsample.pyに対して実行するときは大体こんな感じ。

> %timeit -n 5 %run sample

普通に書く

何もしない時

def fibo(n):
    if n < 2: return n
    return fibo(n-1) + fibo(n-2)


if __name__=="__main__":
    fibo(38)
In [83]: %timeit -n 1 %run sample
1 loops, best of 3: 15.7 s per loop

メモ化的なやつ

def fibo(n):
    a,b = 0,1
    for x in range(n):
        a,b = b,a+b
    return a
In [86]: %timeit -n 5 %run sample
5 loops, best of 3: 745 µs per loop

nを増やす

if __name__=="__main__":
    n = 10**6
    fibo2(n)
In [92]: %timeit -n 1 %run sample
1 loops, best of 3: 11 s per loop

Numba1

単にjitを使ってみる

@jit
def numfibo(n):
    a,b = 0,1
    for x in range(n):
        a,b = b,a+b
    return a
In [98]: %timeit -n 5 %run sample
5 loops, best of 3: 42.6 ms per loop

もっと増やす

if __name__=="__main__":
    n = 10**10
    numfibo(n)
In [116]: %timeit -n 1 %run sample
1 loops, best of 3: 3.32 s per loop

Numba2

型定義を入れる

@jit(int64(int64))
def numfibo2(n):
    a,b = 0,1
    for x in range(n):
        a,b = b,a+b
    return a
In [118]: %timeit -n 1 %run sample
1 loops, best of 3: 3.23 s per loop

少し条件を変えてみる

if __name__=="__main__":
    n = 10**10
    numfibo2(n-2)
    numfibo2(n-1)
    numfibo2(n)

Numba2

In [120]: %timeit -n 1 %run sample
1 loops, best of 3: 9.61 s per loop

ベクトル化

@vectorize([int64(int64)])
def numvfibo(n):
    a,b = 0,1
    for x in range(n):
        a,b = b,a+b
    return a
In [122]: %timeit -n 1 %run sample
1 loops, best of 3: 9.66 s per loop

結果

単にJITを入れるだけでも割と高速化されそうな印象。
型定義はおまけ程度に早くなるのかな?何度やっても多少早かったので。
ベクトル化は使いどころを知らないと高速化出来なさそう。
guvectorizeもあるけど、チュートリアルを見ても使い方がぱっとは分からない割に早くなってくれなかったのでアレゲ。。。

雑記

仕事中に遊びで少し使ってみたけど、数値計算的な所以外ではjitを入れても速くはならなかった。
というより、JIT分遅くなっている所もあるので闇雲に突っ込んでも逆効果かも。
普通のWebアプリケーションだと、計算よりも分岐とか文字列の分離結合のが多いと思うので、案外使い道が無いのではなかろうか?

PythonとSparkであそぼ(1)

背景

<< 略 >>
今をときめくインメモリ分散処理エンジンSparkを使いたいなぁと思ったりそうでもなかったりするから。 SQLチックに使えたり、機械学習エンジンあるしなんかスゲーじゃん?

参考

またどっかの本読んでます。
本家サイトでEarlyReleaseのEbookを買って読んでいたけど、今のKindle価格の方が安かったりするというちょっと残念な話。

Learning Spark: Lightning-Fast Big Data Analysis

Learning Spark: Lightning-Fast Big Data Analysis

続きを読む

「はじめてのR」を頑張って読んだ(1)

背景

いつも通りのビッグデータがうんたらかんたら。 もうちょっと突っ込んでみると、疲れで頭が痛くなって、下を向いて机に突っ伏してたら足元にこの本が転がってたから。

参考

はじめてのR: ごく初歩の操作から統計解析の導入まで

はじめてのR: ごく初歩の操作から統計解析の導入まで

先に感想

値の代入の仕方とcsvの読み出し方くらいです。
入門部分なので、プログラマには殆ど必要ありません。
私は殆ど4章から読み始めました。

続きを読む