2015年12月23日

ベンチマーク9 __slots__

クラスに __slots__ を定義する場合としない場合におけるアトリビュートへのアクセス速度について、ベンチマークを計測します。
__slots__ についてはこちらを参照下さい。


ベンチマークのソースコードです。__slots__ を定義する場合と定義しない場合のそれぞれについて計測します。

from benchmarker import Benchmarker

with Benchmarker(10000000, cycle=3, extra=1) as bench:
    @bench("no slots")
    def _(bm):
        class Sample(object):
            def __init__(self):
                self.sample = 0

        s = Sample()
        for _ in bm:
            s.sample = 1

    @bench("use slots")
    def _(bm):
        class Sample(object):
            __slots__ = ['sample']
            def __init__(self):
                self.sample = 0

        s = Sample()
        for _ in bm:
            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
use slots   3.8496  (100.0) ********************
no slots    4.3632  ( 88.2) ******************
__slots__ を定義する方が高速になりました。
__slots__ を定義しない通常のクラスでは、アトリビュートの追加・削除に備えるため dict を使ってアトリビュートを管理します。dict の処理が必要な分、アトリビュートの追加のないクラスよりも動作が遅くなったと考えられます。

結論としては、__slots__ を定義することで、クラスのサイズを小さくしつつ、さらにアトリビュートへのアクセスも速くすることができる、ということになります。
もちろん、アトリビュートの追加ができなくなるという副作用は忘れてはなりません。

0 件のコメント:

コメントを投稿