PyPyは同じソースを動かしてもPythonよりたいてい速いのですが、遅くなることもあります。その対処法がいくつかあるので紹介していきます。
今回はリストのソートです。こんなコードを動かしてみます。
from itertools import * import time def gen_S(): S = 290797 while True: S = S * S % 50515093 yield S def sort_long(N): a = list(islice(gen_S(), N)) t0 = time.clock() a.sort() print time.clock() - t0 N = 10 ** 7 sort_long(N)
これを動かすと、Pythonで9秒、PyPyで25秒でした。
これがなぜ遅いかというと、リストに多倍長整数が混じっているからのようです。この要素は大きさとしては32ビットの範囲に収まるのですが、掛け算の段階で多倍長整数になって、それがそのまま残ってしまっているのです。次のように変更してみましょう。
def sort_int(N): a = map(int, islice(gen_S(), N)) t0 = time.clock() a.sort() print time.clock() - t0
リストの要素を全て32ビット整数に直してからソートします。そうすると、Pythonで7秒、PyPyで2.3秒でした。まとめると、
Python | PyPy | |
long | 9秒 | 25秒 |
int | 7秒 | 2.3秒 |
【結論】
できることならリストはソートする前に要素をintにしましょう。