スレッド・コンカーレント・Pythonコンパイラ

Pythonで書いたプログラムを高速に実行する仕掛けを調べていたら面白い記事に出会った。そこで公開されているプログラムを紹介しつつ、僕のところで実行した結果を示す。

基本になるプログラム(killing_time.py)は以下のようなものである:


import time


# 単に時間がかかるだけの処理
def killing_time(number):
    return_list = []
    for i in range(1, number + 1):
        if number % i == 1:
            if i <= 9999:
                return_list.append(i)
    return return_list


start = time.time()
num_list = [25000000, 20000000, 20076000, 14500000]
for n in num_list:
    result_list = list(killing_time(n))
stop = time.time()
print('%.3f seconds' % (stop - start))

このプログラムを実行してみた。使った環境はwindows 7でPyhtonのヴァージョンは3.7.6である。
実行結果は
5.763 seconds
このプログラムをスレッド化したもの(killing_time_thread.py)がある。プログラムはここ
実行結果は
5.779 seconds
となり、Pythonスレッドは速度向上には繋がらない。
またこのプログラムを並列処理させるようにしてみる(killing_time_concurrent.py)。プログラムはここ(CPUの最大数は4)。
実行結果は
3.703 seconds
となり、実行速度は若干改良される。
ここまでがオリジナルの記事を追試したもので記事の結果をほぼ再現した。

次にこの三つのプログラムをPythonコンパイラ(pypy)で実行させてみた結果を述べる。pypyのヴァージョンは
Python 3.6.9 (2ad108f17bdb, Apr 07 2020, 03:05:35)
[PyPy 7.3.1 with MSC v.1912 32 bit]
実行結果は


killing_time.py -------------> 0.713 seconds
killing_time_thread.py) -----> 0.462 seconds
killing_time_concurrent.py --> 1.049 seconds

となった。なにも手を入れないプログラムでもコンパイラで実行するとかなりの実行速度向上ができることが分る。

pypyはnumpyモジュールなどの拡張モジュールとの相性が悪い。しかしネイティヴPythonのみを使ったプログラムは高速に実行できる。