LoginSignup
26

More than 5 years have passed since last update.

CPythonとPyPyの速度比較

Last updated at Posted at 2014-03-21

リストに要素を追加する処理速度の比較

前提

処理速度の比較として、Pythonの公式実装であるCPythonと、PythonのPythonによるJITコンパイラ実装であるPyPyの実行時間について比較しました。

Pythonのリスト内包表記で使った以下の3つの関数に対して、Pythonで実行時間を計測する方法 その1で定義したデコレータを用いました。

評価対象の関数

# 1. testfunc1: 空リストを用意してappend
@time
def testfunc1(rangelist):
    templist = []
    for temp in rangelist:
        templist.append(temp)

# 2. testfunc2: 1+appendをオブジェクト化
@time
def testfunc2(rangelist):
    templist = []
    append = templist.append
    for temp in rangelist:
        append(temp)

# 3. testfunc3: リスト内包表記
@time
def testfunc3(rangelist):
    templist = [temp for temp in rangelist]

時間計測用デコレータ

def time(func):
    import functools
    import datetime
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start = datetime.datetime.today()
        result = func(*args, **kwargs)
        end = datetime.datetime.today()
        return end - start
    return wrapper

CPythonとPyPyのバージョンは以下の通りです。

CPython

Python 2.7.4 (default, Apr  6 2013, 19:54:46) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.

PyPy

Python 2.7.3 (87aa9de10f9c, Nov 24 2013, 17:46:53)
[PyPy 2.2.1 with MSC :.1500 32 bit] on win32
Type "help", "copyright", "credits" or "license" for more information
And now for something completely different: ``PyPy 1.3 released''

結果

それぞれの関数に対し、10,000,000個の要素をリストに追加する処理を10回行い、その平均実行時間を取得しました。

CPython

>>> rangelist = range(1,10000000)
>>> print reduce(lambda x, y: x + y, [testfunc1(rangelist) for temp in range(0,10)])/10
0:00:00.998600
>>> print reduce(lambda x, y: x + y, [testfunc2(rangelist) for temp in range(0,10)])/10
0:00:00.723500
>>> print reduce(lambda x, y: x + y, [testfunc3(rangelist) for temp in range(0,10)])/10
0:00:00.399900

PyPy

>>> rangelist = range(1,10000000)
>>> print reduce(lambda x, y: x + y, [testfunc1(rangelist) for temp in range(0,10)])/10
0:00:00.290300
>>> print reduce(lambda x, y: x + y, [testfunc2(rangelist) for temp in range(0,10)])/10
0:00:00.275500
>>> print reduce(lambda x, y: x + y, [testfunc3(rangelist) for temp in range(0,10)])/10
0:00:00.046300

厳密に比較するには、最初の一回を抜いたりいろいろ必要ですが、ここでは何もしていません。

結論

それぞれの倍率(CPythonの実行時間÷PyPyの実行時間)は以下の通りです。数値が大きいほどPyPyが高速であることを意味します。

  • testfunc1: 3.43
  • testfunc2: 2.62
  • testfunc3: 8.63

PyPyでは、testfunc3、つまりリスト内包表記版が特に高速化しています。
JITコンパイラ関連でLuaを勉強しようかなと思っていましたが、これならPyPyを勉強するべきだと思いました。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26