PyPyを速くする(4) 内包表記

例えば、こんなコードがあるとします。

def divs1(N):
    return [ N / n for n in xrange(1, N + 1) ]

N = 10 ** 8
print sum(div1(N))

内包表記ですね。これを間違ってもappendを使って次のように書いてはいけません。

def divs2(N):
    a = []
    for n in xrange(1, N + 1):
        a.append(N / n)
    return a

Pythonでも6.5秒 -> 11.0秒になるのですが、PyPyだと0.86秒 -> 2.53秒と極端に遅くなりました。
たとえ複雑な式で内包表記では書きづらいとしても、内部関数を使ったほうが速いです。

def divs3(N):
    def f(n):
        return N / n    # ここでは単純な関数にしている。
    
    return [ f(n) for n in xrange(1, N + 1) ]   # mapを使うと遅い例も

Pythonでは13.9秒と遅くなりましたが、PyPyでは0.90秒とほとんど変わっていません。
まとめると、

  Python PyPy
内包表記 6.5秒 0.86秒
append 11.0秒 2.53秒
内包表記+内部関数 13.9秒 0.90秒

【結論】
PyPyでは極力内包表記を使いましょう。処理が複雑な場合は内部関数と組み合わせて使いましょう。