Python 목록 (튜플)에 요소 당 몇 바이트가 있습니까?
-
02-07-2019 - |
문제
예를 들어, 백만 (32 비트) 정수 목록을 저장하는 데 얼마나 많은 메모리가 필요합니까?
alist = range(1000000) # or list(range(1000000)) in Python 3.0
해결책 2
유용한 링크:
데이터를 사전에 넣으면 데이터 크기를 어떻게 계산합니까?
그러나 그들은 결정적인 대답을하지 않습니다. 가는 길 :
목록이 있거나없는 Python 통역사가 소비 한 메모리를 측정합니다 (OS 도구 사용).
일종의 크기 (pyobject)를 정의하는 타사 확장 모듈을 사용하십시오.
업데이트:
import asizeof
N = 1000000
print asizeof.asizeof(range(N)) / N
# -> 20 (python 2.5, WinXP, 32-bit Linux)
# -> 33 (64-bit Linux)
다른 팁
"때에 따라 다르지." Python은 달성하는 방식으로 목록에 대한 공간을 할당합니다. 상각 일정한 시간 목록에 요소가 추가됩니다.
실제로, 이것이 현재 구현에서 의미하는 바는 ... 목록에는 항상 2 개의 전력 수의 요소에 대한 공간이 할당 된 공간이 있습니다. 따라서 Range (100000)는 실제로 2^20 요소 (~ 14,045 백만)를 보유 할만 큼 큰 목록을 할당합니다.
이것은 목록 구조 자체를 저장하는 데 필요한 공간입니다 (각 요소의 Python 객체에 대한 포인터 배열). 32 비트 시스템은 요소 당 4 바이트가 필요하며 64 비트 시스템은 요소 당 8 바이트를 사용합니다.
또한 실제 요소를 저장할 공간이 필요합니다. 이것은 크게 다릅니다. 작은 정수 (현재 -5 ~ 256)의 경우 추가 공간이 필요하지 않지만 더 많은 숫자의 경우 Python은 각 정수에 대한 새로운 객체를 할당하며, 이는 10-100 바이트를 사용하고 메모리를 파편화하는 경향이 있습니다.
결론 : 복잡합니다 그리고 파이썬 목록은입니다 ~ 아니다 큰 균질 한 데이터 구조를 저장하는 좋은 방법. 이를 위해 사용하십시오 array
모듈 또는 벡터화 된 수학을 해야하는 경우 Numpy를 사용하십시오.
PS- 튜플은 목록과 달리입니다 설계되지 않았습니다 그들에게 요소가 점진적으로 추가되도록하는 것. 할당 원이 어떻게 작동하는지 모르겠지만 큰 데이터 구조에 사용하는 것에 대해 생각조차하지 않습니다 :-)
질문의 "튜플"을 해결합니다
일반적인 빌드 구성에서 Cpython의 pytuple 선언은 다음과 같습니다.
struct PyTuple {
size_t refcount; // tuple's reference count
typeobject *type; // tuple type object
size_t n_items; // number of items in tuple
PyObject *items[1]; // contains space for n_items elements
};
Pytuple 인스턴스의 크기는 구성 중에 고정되어 있으며 나중에 변경할 수 없습니다. pytuple에 의해 점유 된 바이트의 수는 다음과 같이 계산할 수 있습니다.
sizeof(size_t) x 2 + sizeof(void*) x (n_items + 1)
.
이것은 제공합니다 얕은 튜플 크기. 얻기 위해 가득한 크기는 또한 뿌리 내린 객체 그래프로 소비 된 총 바이트 수를 추가해야합니다. PyTuple::items[]
정렬.
튜플 구조 루틴은 빈 튜플의 단일 인스턴스 만 만들어 져야한다는 점은 주목할 가치가 있습니다 (싱글 톤).
참조 :python.h, 대상 .H, tupleobject.h, tupleobject.c
새로운 기능,
getsizeof()
, 파이썬 객체를 취하고 바이트로 측정 한 물체가 사용하는 메모리의 양을 반환합니다. 내장 객체는 올바른 결과를 반환합니다. 타사 확장은 a를 정의 할 수는 없지만 정의 할 수 있습니다__sizeof__()
객체의 크기를 반환하는 방법.
kveretennicov@nosignal:~/py/r26rc2$ ./python
Python 2.6rc2 (r26rc2:66712, Sep 2 2008, 13:11:55)
[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2
>>> import sys
>>> sys.getsizeof(range(1000000))
4000032
>>> sys.getsizeof(tuple(range(1000000)))
4000024
분명히 반환 된 숫자에는 포함 된 개체 (sys.getSizeof (1) == 12)에 의해 소비 된 메모리가 포함되지 않습니다.
이것은 구현에 따라 다릅니다. 확실히 그것은 정수의 내부 표현에 따라 다릅니다. 파이썬이 임의로 큰 정수를 제공하기 때문에 작은 int가 더 작게 저장되어 있기 때문에 32 비트로 저장 될 것이라고 가정 할 수 없습니다.
내 파이썬 (Core 2 Duo의 Fedora 9의 2.5.1)에서 할당하기 전의 vmsize는 22684KB입니다. 100 만 개의 요소 할당 후 VMSize는 38340KB로갑니다. 이것은 10000000 정수의 경우 약 16000KB를 나타냅니다. 이는 정수 당 약 16 바이트입니다. a 많은 목록에 대한 오버 헤드. 나는이 숫자를 큰 소금으로 가져갑니다.
나는 당신이 왜 묻는 지에 대해 조심합니다. 주어진 구현에 필요한 메모리를 파악하려고 노력하고 있습니까? 당신은 10,000,000 개의 위젯을 읽고 얼마나 많은 RAM이 빨려 있는지 알고 싶습니까?
이 경우 각 위젯이 얼마나 많은 RAM을 취하는지 알아 내려고하지 않고 RAM, 예를 들어 10,000 개의 위젯이 얼마나 많은 양의 RAM을 파악하고 실제 크기를 얻기 위해 곱하십시오.