Windows 10のUbuntuでPythonとPyPy(dict)

PyPyは、たいていの場合Pythonのコードそのものを動かしてもPythonより数倍速くなる。単純な計算ならC++並みに速くなる。
しかし、辞書を扱う部分が主になると途端に遅くなり、Pythonより遅くなる。
UbuntuPython/PyPyではどうなるのか調べてみた。

#!/usr/bin/python

import sys
import time

def f(N):
    dic = { }
    for n in xrange(N):
        dic[n] = n
    
    s = 0
    for n in xrange(N):
        s += dic[n]
    return s

t0 = time.clock()
N = 10 ** 7
for k in range(10):
    print f(N)
print >>sys.stderr, time.clock() - t0

辞書につっこんで、辞書から取り出すだけである。結果は、

Python(Win)    22.7sec
PyPy(Win)      13.6sec
Python(Ubuntu) 15.5sec
PyPy(Ubuntu)   11.2sec

思ったような結果にならなかった。もう少し複雑な辞書の使い方をしなければならないのだろうか。

#!/usr/bin/python

from itertools import *
from math import sqrt
import sys
import time

def count_primes(n):
    m = int(sqrt(n))
    keys = [ n / i for i in range(1, m + 1) ]
    keys += range(keys[-1] - 1, 0, -1)
    h = {i : i - 1 for i in keys}
    for i in range(2, m + 1):
        if h[i] > h[i - 1]:
            hp = h[i - 1]
            i2 = i * i
            for j in keys:
                if j < i2: break
                h[j] -= h[j / i] - hp
    
    return h[n]

t0 = time.clock()
N = 10 ** 11
print count_primes(N)
print >>sys.stderr, time.clock() - t0

これはどこかから拾ってきた素数の個数を数えるコード。

Python(Win)    38.3sec
PyPy(Win)      53.5sec
Python(Ubuntu) 18.8sec
PyPy(Ubuntu)   12.5sec

と、PythonとPyPyが逆転した。