2015年12月24日

ベンチマーク10 __dict__

クラスのアトリビュートへのアクセス速度について、__dict__ を使う方法と、setattr() / getattr() を使う方法の、ベンチマークを計測します。


まず、アトリビュートに値を代入する場合について、ベンチマークを計測します。
ベンチマークのソースコードです。

from benchmarker import Benchmarker

with Benchmarker(10000000, cycle=3, extra=1) as bench:
    class Sample(object):
        def __init__(self):
            self.sample = 0
    s = Sample()

    @bench("__dict__")
    def _(bm):
        for _ in bm:
            s.__dict__['sample'] = 1

    @bench("setattr")
    def _(bm):
        for _ in bm:
            setattr(s, 'sample', 1)

計測結果です。
## benchmarker:         release 4.0.1 (for python)
## python version:      3.4.0
## python compiler:     MSC v.1600 32 bit (Intel)
## python platform:     Windows-8-6.2.9200
...

## Ranking    real
__dict__    5.6670  (100.0) ********************
setattr     8.3321  ( 68.0) **************
__dict__ を用いた方が高速です。


続いて、アトリビュートの値を取得する場合について、ベンチマークを計測します。
ベンチマークのソースコードです。

from benchmarker import Benchmarker

with Benchmarker(10000000, cycle=3, extra=1) as bench:
    class Sample(object):
        def __init__(self):
            self.sample = 0
    s = Sample()

    @bench("__dict__")
    def _(bm):
        for _ in bm:
            s.__dict__['sample']

    @bench("getattr")
    def _(bm):
        for _ in bm:
            getattr(s, 'sample')

計測結果です。
## benchmarker:         release 4.0.1 (for python)
## python version:      3.4.0
## python compiler:     MSC v.1600 32 bit (Intel)
## python platform:     Windows-8-6.2.9200
...

## Ranking                real
__dict__                5.4146  (100.0) ********************
getattr                 7.1281  ( 76.0) ***************
こちらも、__dict__ を用いた方が高速となりました。


結果より、__dict__ を用いる方が setattr() / getattr() が高速でした。この結果だけを見ると、__dict__ を使いたくなってしまいます。
しかし! こちらで述べたように、__dict__ はクラスのインターフェースを考慮せずに内部情報に直接アクセスします。所構わず使っていると、良くない結果に繋がりかねません。
__dict__ を使うのは速度が必要になった時の最終手段、ということを忘れないようにしましょう。

0 件のコメント:

コメントを投稿