PyPyがCより速いケース

パイパイ(この名前ちょっとヤバいね)は場合によってはCより速いコードを生成することがあるという例。決してPyPyが一般的にCより速いと主張しているわけでないない。

http://morepypy.blogspot.com/2011/02/pypy-faster-than-c-on-carefully-crafted.html

どうしてこういうことになるかというと、Cはモジュール(.o)の壁を越えて関数をインラインすることができないからだ。JITはそんなものおかまいなしにインラインすることができる。動的最適化の利点だ。

Python

x.py


def add(a, b):
return a + b
y.py:

from x import add
def main():
i = 0
a = 0.0
while i < 1000000000:
a += 1.0
add(a, a)
i += 1
main()

C

x.c


double add(double a, double b)
{
return a + b;
}

y.c


double add(double a, double b);

int main()
{
int i = 0;
double a = 0;
while (i < 1000000000) {
a += 1.0;
add(a, a);
i++;
}
}

Cに不利な状況を無理して作った感じだ。

結果


1.97s - PyPy
3.07s - C

コンパイルオプション

PyPy trunk (386ed41eae0c), running pypy-c y.py
C - gcc -O3 (GCC 4.4.5 shipped with Ubuntu Maverick)

ご覧のとうりPyPyの方がCより50%速い。PyPyはCコンパイラが行うような最適化を施しさらにモジュールを越えたインライン化をJITでやるらしい。この違いはCだけでなくJavaでも見られるとのこと。

Steve Yeggieの言葉を思い出す:
(意訳)「動的言語は本質的に静的言語より遅いんじゃない。ただ研究が遅れているだけだ。そのうち追い付くだろう」