import sys
sys.getsizeof(obj)
sys
모듈의 getsizeof
함수로 오브젝트의 크기를 구할 수 있다.
int
타입의 값을 반환하고,
그 값은 메모리 상에서 차지하는 바이트 수를 의미한다.
https://docs.python.org/3/library/sys.html#sys.getsizeof
크기는 하드웨어와 버전, 구현체에 따라 다를 수 있다.
64비트 윈도의 파이썬3 기준으로,
어떤 결과가 나오는 지 주석으로 적었다.
print(sys.getsizeof(None)) # 16
print(sys.getsizeof(object())) # 16
파이썬의 내장 객체는 기본적으로
가비지 컬렉션을 위한 ssize_t
(64비트이므로 8바이트) 레퍼런스 카운트와,
타입 정보에 대한 포인터 (64비트이므로 8바이트)로 구성되어 있다.
print(sys.getsizeof(0)) # 24
print(sys.getsizeof(1)) # 28
print(sys.getsizeof(2 ** 30)) # 32
print(sys.getsizeof(2 ** 60)) # 36
print(sys.getsizeof(-1)) # 28
파이썬에서 정수는 임의 정밀도(Arbitrary-precision, Bignum) 방식이기 때문에
숫자가 증가할 수록 크기가 늘어난다.
https://rushter.com/blog/python-integer-implementation/
레이아웃을 알아보니 정수는
레퍼런스 카운트와 타입 정보에 대한 포인터,
int
가 임의 정밀도이기 위해 필요한 ssize_t
크기 정보,
각 수를 나타내는 uint32_t[]
digit
데이터 로 구성되어있다.
print(sys.int_info)
# sys.int_info(bits_per_digit=30, sizeof_digit=4, default_max_str_digits=4300, str_digits_check_threshold=64
2의 30승마다 증가하고 digit
크기는 4바이트임을 알 수 있다.
0은 크기가 없는 상태다. 그러므로 24바이트.
print(sys.getsizeof(False)) # 24
print(sys.getsizeof(True)) # 28
True
가 False
보다 4바이트 많다.
파이썬에서 bool은 int의 서브클래스로 구현됐기 때문이다.
https://docs.python.org/3/c-api/bool.html
print(sys.getsizeof(0.0)) # 24
print(sys.getsizeof(1.0)) # 24
float
는 IEEE 754를 그대로 사용한다.
기본적인 오브젝트 구조에 double의 8바이트가 더해져 24바이트로 나왔다.
https://github.com/python/cpython/blob/main/Include/cpython/floatobject.h
print(sys.getsizeof('')) # 49
print(sys.getsizeof('a')) # 50
print(sys.getsizeof('aa')) # 51
print(sys.getsizeof('あ')) # 76
print(sys.getsizeof('あa')) # 78
str
의 경우,
a
가 하나씩 늘어날 때마다 1바이트 늘어나는 건 직관적이지만,
어째서 아스키 문자가 아닌 あ
가 있을 때는 왜 74바이트로 시작하는 것이고,
같은 a
가 추가될 때 2바이트씩 늘어나는 지...
이런 현상은 파이썬의 문자열 처리 방식 때문이다.
https://rushter.com/blog/python-strings-and-memory/
あ
는 Latin-1 밖에 있으므로
문자열은 UCS-2 문자열이 되어
한 문자에 2바이트씩 차지하게 된 것이다.
한글도 BMP(Basic Multilingual Plane) 상에 있으므로,
한글이 들어간 문자열도 2바이트씩을 차지하게 된다.
그 외에 왜 빈 문자열이 49바이트인지,
UCS-2 문자열이 74바이트가 기본인지는...
부가 정보가 많아서 그렇다.
그 외 컬렉션이든 변수든 참조를 기반으로 하는 경우가 많아서 더 건질 정보는 딱히 없는 것 같다.
시·공간적 효율 측면에서 표준 라이브러리나 NumPy
의 array
를 사용하는 경우도 있으니 참고.
이렇게 주구장창 적어놓긴 했지만 이걸 알아서 딱히 효율적이게 되진 않을 거라 본다.
애초에 파이썬을 쓸 때 메모리가 걱정이면 파이썬을 안 쓰면 되니까.
궁금했는데 잘 봤습니다