そうだ! EuroPython 2011へ行こう

#3 PyPyについての講演,ハンズオン,スプリント

この記事を読むのに必要な時間:およそ 5 分

PyPy HANDS-ON:PyPyハンズオン

PyPy HANDS-ONセッションの内容は次の2つを予定していました。

  • Part1:アプリケーションをPyPyで動かす
  • Part2:PyPyを使用して独自のインタプリタを書く

しかし残念ながら,時間の都合上,Part2に達することはできませんでした。

PyPy HANDS-ON

PyPy HANDS-ON

PyPy環境の構築

Part1に入る前にPyPyの環境を作りましょう。

まずはPyPy1.5を用意します。PyPy.1.5のダウンロードはこちらです。

インストールに関するドキュメントはこちらです。

bitbucket.orgのPyPyリポジトリからpypyのパッケージを持ってきてください。

$ hg clone http://bitbucket.org/pypy/pypy
$ cd pypy
$ hg up -r release-1.5

次に,JITコンパイラのログファイルを解析を助けるツールjitviewerをインストールします。jitviewerは他のパッケージに依存しており,それらのパッケージをインストールするために,distributeをインストールすることを推奨します。

distributeのインストールは次の通りです。

$ curl -O http://python-distribute.org/distribute_setup.py
$ /path/to/pypy-1.5/bin/pypy distribute_setup.py

また,サードパーティーのライブラリをインストールしたいのであれば,pipをインストールすることをお勧めします。

$ curl -O https://github.com/pypa/pip/raw/master/contrib/get-pip.py
$ /path/to/pypy-1.5/bin/pypy get-pip.py

distributeがインストールされたら,jitviewerをインストールします。

$ hg clone http://bitbucket.org/pypy/jitviewer
$ cd jitviewer
$ /path/to/pypy-1.5/bin/pypy setup.py develop
Part1:アプリケーションをPyPyで動かす

Part1では,アプリケーションをPyPyで動かしたいユーザ向けに,次のような内容でした。

  • PyPy JITコンパイラの概要説明
  • PyPyの試し方
  • JITコンパイラにより生成されたトレースログを表示する方法
  • PyPyのバグとバグフィックス
Just-in-Timeコンパイラ

PyPyのJust-in-Time(JIT)コンパイラについての説明です。JITコンパイラはコード実行時に,最適化されたマシンコードを自動生成するアーキテクチャです。

例えば,ループの場合,抽象構文木に変換後,値の型,条件分岐を記録し,最適化されたバイトコードを生成します。しばしば条件分岐の記録が失敗しますが,その際は,失敗した箇所から再度トレースを開始する仕組みになっています。

JITコンパイラはIntel x86,amd64プロセッサをサポートしており,直にARMをサポート予定です。またMozilaプロジェクトのTraceMonkeyによく似たアーキテクチャです。

PyPyのPythonインタプリタは高水準言語であるRPythonで書かれています。JITコンパイラジェネレーションを使い,このRPythonのコードからJITコンパイラを自動生成しています。

PyPyを試してみる

PyPy HANDS-ON

PyPy HANDS-ON

PyPyを実行するには,次のように簡単に実行できます。

$ pypy program.py

ここでCPythonより速い,簡単なコードを実演します。次のcount.pyは5の倍数と5の倍数ではない数字の個数をカウントするコードです。

import sys
import time

def count_mult_of_5(N):
    mult = 0
    not_mult = 0
    for i in range(N):
        if i % 5 == 0:
           mult += 1
    else:
        not_mult += 1
    return mult, not_mult

 def main():
     N = int(sys.argv[1])
     start = time.clock()
     count = count_mult_of_5(N)
     end = time.clock()
     print 'count: ', count
     print 'time:', end-start, 'secs'

 if __name__ == '__main__':
     main()

PyPyで実行してみます。

$ /path/to/pypy-1.5/bin/pypy count.py 10000000
count: (2000000, 8000000)
time: 0.17 secs

Python2.7で実行してみます。

$ python2.7 count.py 10000000
count: (2000000, 8000000)
time: 1.67 secs

Python2.7よりもPyPyの処理速度が速い結果となりました。

次に,JITコンパイラのログを取ってみましょう。JITコンパイラのログは次の通り,環境変数PYPYLOGを設定する事によって出力できます。

$ PYPYLOG=jit:log /path/to/pypy-1.5/bin/pypy count.py 10000000

その結果,logファイルが生成されます。

jitviewerPyPyのJITコンパイラが生成するログファイルの分析ツールです。実際にjitviewerを起動してみます。

$ PYTHONPATH=/path/to/pypy/ /path/to/jitviewer.py log

jitviewerが起動したらhttp://localhost:5000/へウェブブラウザでアクセスします。リンクをクリックすると展開され,Pythonバイトコード命令が表示されます。

jitviewer

jitviewer

Pythonバイトコード命令の詳細は,Python公式ドキュメントのPython Bytecode Instructionsを確認下さい。

著者プロフィール

森本哲也(もりもとてつや)

一介のプログラマ。

自分で設計して,自分で開発して,自分で直せるような独立したプログラマを目指している。OSSコミュニティのゆるい人のつながりが性にあっていてPythonプログラミングが好き。共訳書に『エキスパート Pythonプログラミング』(アスキーメディアワークス)がある。

Twitter:@t2y

ブログ:http://d.hatena.ne.jp/t2y-1979/


池徹(いけとおる)

プログラミング言語全般を好み,特にJavaScriptとPythonを愛する。好奇心旺盛で学ぶことは大好きであるが,最近の関心はもっぱらPyPy。休日の楽しみは読書に,美術館巡り。現在はオーストラリアの会社で開発をしつつ忍者の肩書きを授かる。

Twitter:http://twitter.com/#!/rokujyouhitoma
ブログ:http://d.hatena.ne.jp/rokujyouhitoma

コメント

コメントの記入