このBlogは移転しました。今後は aish.dev を御覧ください。

Python3.3のdecimalが馬鹿っぱやい件

Python 3.3 では decimalモジュールがC言語で実装され、10進浮動少数演算が馬鹿っぱやになりました。

単純なニュートン法平方根を計算してみると、

def newton(n):
    guess = n/2
    better = (guess + n/guess)/2
    while better != guess:
        guess = better
        better = (guess + n/guess)/2
    return guess

Python2.7では

浮動少数点
$ python -m timeit "import decimal;import newton;newton.newton(2.0)"
100000 loops, best of 3: 2.73 usec per loop
decimal
$ python -m timeit "import decimal;import newton;newton.newton(decimal.Decimal('2.0'))"
1000 loops, best of 3: 649 usec per loop


Python 3.3では

浮動少数点
$ python3 -m timeit "import decimal;import newton;newton.newton(2.0)"
100000 loops, best of 3: 3.56 usec per loop
decimal
$ python3 -m timeit "import decimal;import newton;newton.newton(decimal.Decimal('2.0'))"
100000 loops, best of 3: 13.6 usec per loop

速くなったとは言ってもfloatの数倍はかかってしまうレベルではあるが、それでももともとPython浮動小数点演算なんて別に速いというほどのものではない。どっちにしろ遅いんだから、この程度の差なら数値演算が主なスクリプト以外では、全てDecimalで済ませてしまっても問題ないというレベルではないだろうか。