Python의 모든 클래스는 인스턴스 속성(instance attribute)
을 가집니다. 기본적으로, 이러한 객체의 인스턴스 속성을 관리하기 위해 Python에서 내부적으로 딕셔너리를 사용합니다. 객체의 __dict__
필드에 접근하여 인스턴스 속성들을 딕셔너리 형태로 확인할 수 있고, 이는 런타임에 새로운 속성을 설정하는 데에 매우 유용하게 사용됩니다.
그러나, 알려진(known) 속성
들로 구성된 클래스들의 경우 이러한 구조는 딕셔너리가 낭비하는 RAM 때문에 병목이 발생할 수 있습니다. 클래스 레벨에 __slots__
라는 변수를 설정해서, 해당 클래스에 의해 만들어진 객체의 인스턴스 속성 관리에 딕셔너리 대신 속성에 대한 고정된(fixed) set을 사용하도록 할 수 있습니다.
__slots__가 정의된 클래스의 인스턴스에는 __dict__ 필드가 없다 정도밖에 차이가 없어 보이지만, IronPython의 도움을 받아 메모리 사용량을 보면, 효율이 확실히 개선된 것을 확인할 수 있습니다. ipython-memory-usage
를 사용해, 1024 * 256
개의 객체 생성에 대한 메모리 사용량을 확인해 보았습니다.
In [1]: class WithoutSlots:
...: def __init__(self, name, identifier):
...: self.name = name
...: self.identifier = identifier
...:
In [2]: class WithSlots:
...: __slots__ = ['name', 'identifier']
...: def __init__(self, name, identifier):
...: self.name = name
...: self.identifier = identifier
...:
In [3]: import ipython_memory_usage.ipython_memory_usage as imu
In [4]: size = 1024 * 256
In [5]: imu.start_watching_memory()
In [5] used 0.0000 MiB RAM in 5.31s, peaked 0.00 MiB above current, total RAM usage 15.57 MiB
In [6]: x = [WithoutSlots(1, 1) for _ in range(size)]
In [6] used 22.6680 MiB RAM in 0.80s, peaked 0.00 MiB above current, total RAM usage 38.24 MiB
In [7]: x = [WithSlots(1, 1) for _ in range(size)]
In [7] used 9.3008 MiB RAM in 0.72s, peaked 0.00 MiB above current, total RAM usage 47.54 MiB
'Python 계열 > Python 레거시 글' 카테고리의 다른 글
requirements.txt로 협업 상황에서의 의존성 관리하기 (0) | 2018.11.07 |
---|---|
pip (0) | 2018.11.05 |
Context Manager (0) | 2018.11.01 |
Argument Unpacking (0) | 2018.10.30 |
[Python] zip (0) | 2018.07.28 |