Keep on moving

あんまりまとまってないことを書きますよ

PyPy Advent Calendar 5日目 - PyPyとCPythonの違いを知ろう

このエントリは PyPy Advent Calendar 2011 の5日目として書いています.

前日の @ さんからバトンを受け取りました。
みなさん、PyPyを楽しまれていますでしょうか。
PyPyはよくCでのPython処理系に比べて早い(こともある)という点 *1 が有名ですが、他に違いはあるのでしょうか?
本日は実装系としてのPyPyはCPythonとどの辺が違うかを見ていきます。

本家ドキュメント

本家にドキュメントがあります。

私の方で翻訳中のものはこちらです。1.5のときに翻訳したものなので、最新版には追随できてません。
@ さんのところで公開されてましたので参照下さい。

ざっくりと違いを解説

翻訳だけ紹介するのもなんですのでざっくりと解説します。
理解できていないところもありますので、間違ってるところがあったらご指摘をお願いします!!

Cで書かれてるモジュールの扱い

PyPyは RPythonで実装されてるため、CPythonの全ての組み込み関数が使えるわけではないようです。
pypy/module/にあるものと、
(できる限り ctypes を使って)Pure Pythonで書きなおされた lib_pypyにあるもの (cPickle など)が使えるようです。

GCの動作の違い

PyPyとCPythonではGCの動作が違うため、 __del__ メソッドの挙動が変わります。
たとえば以下のようなPythonコードがあったとします。

pypy_cpy_difference.py

class delTest(object):
    def __init__(self):
        print("__init__")
    def __del__(self):
        print("__del__")

def test():
    x = delTest()

if __name__=="__main__":
    print("start func")
    test()
    print("endfunc")


Pythonでの実行結果は以下です。__del__メソッドが呼ばれています。

$ python pypy_cpy_difference.py
start func
__init__
__del__
endfunc

PyPy1.7での実行結果は以下です。__del__メソッドが呼ばれていないことがわかります。

$ pypy pypy_cpy_difference.py
start func
__init__
endfunc

__del__ メソッドでのリソース解放などを前提としたコードを書くと痛い目にあいそうですね。

明日

明日は @ さんです。明日もお楽しみに。

*1: ここなど [http://speed.pypy.org/]