Python速度アップ考

Python速度アップ考
2021/10/23

 最近はプログラムをいじることはありませんが、マーク・ルッツ著「Learning Python」をパラパラと読み返しています。 Python でコーディングした今はなるほどという部分も多いです。 この本の中でも、Pypy の速さに触れていますが、Python の弱点といわれるループ計算とその代替手段について調べているとことがあります。 面白いので、自分でも調べてみようと思い、本では触れられていない、Pypy での結果に加え、numpy, Cython, cupy でも計測してみました。 計測に使ったソースは以下になります (本のプログラムに手を加えました。 ちなみに書物のプログラムは公開可と書いてあります)。

処理速度計測スクリプト

import sys, time
import numpy as np # 追加
reps = 10000000
repslist = list(range(reps))
repslistn = np.arange(0, reps) # 追加

timer = time.clock if sys.platform[:3] == 'win' else time.time

def forLoop():
    res = []
    for x in repslist:
        res.append(abs(x))
    return res

def listComp():
    return [abs(x) for x in repslist]

def mapCall():
    return list(map(abs, repslist))

def genExpr():
    return list(abs(x) for x in repslist)

def genFunc():
    def gen():
        for x in repslist:
            yield abs(x)
    return list(gen())

def numPy(): # 追加
    return np.abs(repslistn).copy()

for func in (forLoop, listComp, mapCall, genExpr, genFunc, numPy): # 追加
    start = time.time()
    res = func()
    print('%9s %1.5f' % (func.__name__, time.time() - start))

Python, pypy 処理速度の比較

 そして、そのその結果が次表です。 Cythonの結果はここに書いていませんが、forループで0.30530秒、内包表記で0.37105秒でした。 ただ、これは変数の型指定などが適当で、修正の余地もあり、表には書き入れませんでした (forループが速いのはC言語がそれを不得意にしていないからでしょう)。

計算方法 Python3 Pypy3 Pypy2
forループ 0.75638 0.43605 0.42708
内包表記 0.54036 0.06576 0.05122
map 0.21357 0.31909 0.09990
式ジェネレータ 0.55462 0.41918 0.38205
関数〃 0.55665 0.40569 0.35905
numPy 0.15842 0.06621 -
cuPy 0.00729 - -
単位: 秒

 すぐにわかるのは、いずれの Python にしろ、for ループは遅く、numpy やリスト内包表記が速いということです。 式ジェネレータ、関数ジェネレータというのは、yield を使い、関数の戻り値を漸次返し、時間消費の効率化を図る比較的新しい手法です。

GPU を使う、cupy の別格の速さ

 この中では、Pypyでは内包表記を使う方法、Python3ではnumpyを使う方法がスピードアップにとって比較的いい感じがします。 GPU を使う cupy はforループを使うより100倍以上速いですが、これは別格で、CPU 処理とのやりとりが多いとかなりスピードダウンするとも聞きます。 ディープラーニング、AI画像、ビデオ、LLMといった用途には大きな威力を発揮するでしょう。

 スピードの追求はきりがないですが、まあ速いにこしたことはないわけで、いろいろ考えさせられます。

コメント  記事が気に入ったらいいねしてね! 0  4  

Facebookシェア   
Python の for ループは遅く、内包表記や numpy で高速化可能。Pypy では内包表記、Python3 では numpy が効果的。GPU利用の cupy は別格で大幅高速化が可能だが、CPU とのデータやり取りで減速する場合もある...
JS詰将棋を Perl から Python へ移植し速度差を検証。CPython は Perl より遅く、PyPy でも大差なし。Python は可読性や拡張性に優れるが型変換やスコープ管理が煩雑で、文字列処理では Perl の利便性を再認識...
オライリー本「Learning Python」を流し読みし、Pythonの構造や多機能性、主要企業での採用状況に感銘。JSに似た特徴や最新機能を学んだ...