Python のスロットについて

Marion Paul Kenneth Mendoza 2023年6月21日
Python のスロットについて

クラスのオブジェクトを作成するにはメモリが必要であり、保存された属性はディクショナリの形式になっています。 何千ものオブジェクトを割り当てる必要がある場合、大量のメモリとインデックス作成に時間がかかります。

スロットまたは __slots__ は、オブジェクトのサイズを縮小し、インデックス作成を高速化する独自のメカニズムを提供します。 この記事では、slots 定数変数が Python でどのように機能するか、およびそれが辞書を使用するよりも優れていることについて説明します。

Python のスロットについて

スロットは、Python コードのランタイムを改善するオブジェクトのメモリ最適化の概念です。 たとえば、クラスからカスタム オブジェクトを作成する場合、辞書に格納されたオブジェクトの属性は __dict__ と呼ばれます。

さらに、オブジェクトの作成後に動的に新しい属性を作成することができます。

スロットがない場合、オブジェクトは次のスニペットのようになります。

コード例:

class sample_class(object):
    def __init__(self, *args, **kwargs):
        self.key = "foo"
        self.value = "bar"


if __name__ == "__main__":
    sample_object = sample_class()
    print(sample_object.__dict__)

出力:

{'key': 'foo', 'value': 'bar'}

Python では、各オブジェクトに、属性の追加をサポートする動的ディクショナリがあります。 すべてのインスタンス オブジェクトに対してディクショナリ インスタンスがあり、余分なスペースを占有し、大量の RAM を浪費します。

Python でオブジェクトを作成する場合、そのすべての特性を格納するために一定量のメモリを割り当てるデフォルトの機能はありません。

設定された数の属性にスペースを割り当てる __slots__ を利用すると、スペースの浪費が減り、プログラムが高速化されます。

コード例:

class sample_class(object):
    __slots__ = ["key", "value"]

    def __init__(self, *args, **kwargs):
        self.key = "foo"
        self.value = "bar"


if __name__ == "__main__":
    sample_object = sample_class()
    print(sample_object.__slots__)

出力:

['key','value']

__slots__ 変数を呼び出すときは、ディクショナリ内の各値をマップするためのキーのみにアクセスすることに注意してください。 Python の辞書は信じられないほど直感的ですが、数千または数百万のアイテムを同時に作成しようとすると問題が発生する可能性があります。

  1. 辞書にはメモリが必要です。 何百万ものオブジェクトが RAM の使用量を使い果たします。
  2. 実際、辞書はハッシュ マップです。

したがって、ディクショナリとスロットの実行時間の違いは、いくつかの属性では目立たないかもしれませんが、データが大きくなるにつれて、スロットを使用したことを嬉しく思います。 属性にアクセスするときの実行時間を約 10% 節約できます。

コード例:

import timeit


class sample_class(object):
    def __init__(self, *args, **kwargs):
        self.key = "foo"
        self.value = "bar"


class sample_class_slots(object):
    __slots__ = ["key", "value"]

    def __init__(self, *args, **kwargs):
        self.key = "foo"
        self.value = "bar"


if __name__ == "__main__":

    time = timeit.timeit("t.key", "from __main__ import sample_class; t=sample_class()")
    time_slots = timeit.timeit(
        "t.key", "from __main__ import sample_class_slots; t=sample_class_slots()"
    )

    print("Time without Slots: ", time)
    print("Time with Slots: ", time_slots)

出力:

Time without Slots:  0.0202741
Time with Slots:  0.0200698
Marion Paul Kenneth Mendoza avatar Marion Paul Kenneth Mendoza avatar

Marion specializes in anything Microsoft-related and always tries to work and apply code in an IT infrastructure.

LinkedIn