2017-03-13 4 views
1

sys.getsizeof(4)으로 전화하면 14을 반환합니다. 이 값이 C에서 sizeof()과 같다고 가정하면 이는 허용 할 수 없을 정도로 높습니다.정수 저장에 사용되는 메모리 양을 제한하는 방법은 무엇입니까?

나는 메모리 배열을 크고 원시 배열의 바이트처럼 사용하고 싶습니다. 메모리 오버 헤드는 문제의 프로젝트에있는 배열의 크기 때문에 최우선 순위에 있습니다. 이식성은 큰 문제이기도하므로 C로 떨어지거나 좀 더 이국적인 라이브러리를 사용하는 것이 최적이 아닙니다.

표준 Python 3 만 사용하여 파이썬이 단일 양수 서명 된 바이트 목록 또는 튜플 멤버에 대해 메모리를 적게 사용하도록하는 방법이 있습니까?

+1

라이브러리를 사용할 수 있다면 [numpy'] (http://www.numpy.org/)는 최적화 된 배열과이를 조작하는 효율적인 함수를 제공합니다. 배열의 dtype 매개 변수를 사용하여 요소의 메모리 크기를 지정할 수 있습니다. – Craig

+1

적절한 _ 유형 코드와 함께'array.array()'를 사용해보십시오. – martineau

+0

marineau의 의견에 따라 : 표준 라이브러리의 일부인 ['array' 모듈] (https://docs.python.org/library/array.html) 문서. –

답변

1

14 파이썬 객체에 적어도 a pointer to its type struct and a refcount이 있어야한다고 생각하면 다소 저조합니다.

의 PyObject

모든 객체 유형이 유형의 확장입니다. 이것은 객체에 대한 포인터를 객체로 취급하는 데 필요한 정보가 들어있는 유형입니다. 일반적인 "릴리스"빌드에서는 객체의 참조 횟수와 해당 유형 객체에 대한 포인터 만 포함합니다. 실제로 PyObject로 선언 된 것은 없지만 Python 객체에 대한 모든 포인터는 PyObject *로 캐스팅 할 수 있습니다. 멤버에 대한 액세스는 Py_REFCNT 및 Py_TYPE 매크로를 사용하여 수행해야합니다.

이 오버 헤드는 모든 Python 개체에 대해 갖게됩니다. 오버 헤드/페이로드 비율을 줄이는 유일한 방법은 예를 들어 배열 (보통 파이썬과 numpy 모두)에서 페이로드가 더 많도록하는 것입니다.

여기에있는 속임수는 배열 요소가 일반적으로 파이썬 객체가 아니기 때문에 refcount와 type 포인터를 없애고 기본 C 유형만큼의 메모리를 차지할 수 있다는 것입니다.

1

서명되지 않은 바이트 만이 염려되는 경우

(모자 팁 마티his comment에 대한 ... 에() 값은 [0, 255]), 그 간단한 대답 내장 될 수 bytearray 및 그 불변의 형제, bytes. 하나의 잠재적 인 문제는 이러한 인코딩 문자열을 (를 읽거나 외부 세계에 작성) 나타 내기위한, 그래서 기본 __repr__이 정수가 아닌 목록, "문자열과 같은"입니다한다는 것이다 :

>>> lst = [0x10, 0x20, 0x30, 0x41, 0x61, 0x7f, 0x80, 0xff] 
>>> bytearray(lst) 
bytearray(b'\x10 0Aa\x7f\x80\xff') 
>>> bytes(lst) 
b'\x10 0Aa\x7f\x80\xff' 

참고 공백, '0', 'A''a'은 문자 그대로 표시되지만 "인쇄 할 수없는"값은 '\x##' 문자열 이스케이프 시퀀스로 표시됩니다. 만약 그 바이트들을 정수 들인의 묶음으로 생각하려고한다면, 이것은 당신이 원하는 것이 아닙니다.

고정 폭 정수 또는 부동 소수점의 동질 배열 (C와 유사)의 경우 표준 라이브러리의 array module을 사용하십시오.

더 복잡한 데이터의 경우
>>> import array 

# One megabyte of unsigned 8-bit integers. 
>>> a = array.array('B', (n % 2**8 for n in range(2**20))) 
>>> len(a) 
1048576 
>>> a.typecode 
'B' 
>>> a.itemsize 
1 
>>> a.buffer_info() # Memory address, memory size. 
(24936384, 1048576) 

>>> a_slice = a[slice(1024, 1040)] # Can be sliced like a list. 
>>> a_slice 
array('B', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]) 
>>> type(a_slice) # Slice is also an array, not a list. 
<class 'array.array'> 

struct module 많은 C의 struct 키워드와 같은 이기종 기록을 포장입니다. C와 달리 arraystruct으로 만드는 확실한 방법이 없습니다.

이러한 데이터 구조는 모두 파이썬의 Buffer Protocol을 사용합니다 (CPython에서는 최소한) 파이썬 클래스가 내부 파이썬 배열을 다른 파이썬 코드에 직접 노출 할 수있게합니다. 뭔가 복잡한 작업이 필요한 경우이 것을 배워야 할 수도 있습니다 ... 또는 NumPy을 포기하고 사용하십시오.