복붙노트

[PYTHON] 왜 int는 파이썬에서 3 배의 메모리를 필요로합니까?

PYTHON

왜 int는 파이썬에서 3 배의 메모리를 필요로합니까?

64 비트 시스템에서 파이썬의 정수는 24 바이트를 차지합니다. 이것은 예를 들어, 3 배의 메모리가 필요합니다. 64 비트 정수의 경우 C입니다. 자, 파이썬 정수가 객체이기 때문입니다. 그러나 추가 메모리는 무엇에 사용됩니까? 나는 나의 추측을 가지고있다. 그러나 확실히 알고있는 것은 멋질 것이다.

해결법

  1. ==============================

    1.파이썬 int 타입은 C int와 같은 제한된 범위를 가지고 있지 않다는 것을 기억하십시오; 유일한 제한은 사용 가능한 메모리입니다.

    파이썬 int 타입은 C int와 같은 제한된 범위를 가지고 있지 않다는 것을 기억하십시오; 유일한 제한은 사용 가능한 메모리입니다.

    메모리는 값 저장, 정수 저장 장치의 현재 크기 (저장 공간 크기는 임의의 크기를 지원하기 위해 가변적 임), 표준 Python 객체 부기 (관련 객체 및 참조 카운트에 대한 참조)로 간다.

    longintrepr.h 소스를 찾을 수 있습니다 (파이썬 3 int 타입은 전통적으로 파이썬 2에서 긴 타입으로 알려짐). 그것은 정수 크기를 추적하기 위해 PyVarObject C 타입을 효과적으로 사용합니다 :

    struct _longobject {
            PyObject_VAR_HEAD
            digit ob_digit[1];
    };
    

    ob_digit 배열은 너비가 15 또는 30 비트 인 '숫자'를 저장합니다 (플랫폼에 따라 다름). 그래서 내 64 비트 OS X 시스템에서 최대 정수는 (2 ^ 30) - 1은 1 'digit'을 사용합니다.

    >>> sys.getsizeof((1 << 30) - 1)
    28
    

    하지만 숫자에 두 개의 30 비트 숫자를 사용하면 추가로 4 바이트가 필요합니다.

    >>> sys.getsizeof(1 << 30)
    32
    >>> sys.getsizeof(1 << 60)
    36
    >>> sys.getsizeof(1 << 90)
    40
    

    기본 24 바이트는 객체 크기, 참조 카운트 및 타입 포인터 (64 비트 OS X 플랫폼에서 각각 8 바이트 / 64 비트)를 보유한 PyObject_VAR_HEAD 구조체입니다.

    파이썬 2에서 정수 <= sys.maxint,> = -sys.maxint - 1은 단일 값만 저장하는보다 간단한 구조를 사용하여 저장됩니다.

    typedef struct {
        PyObject_HEAD
        long ob_ival;
    } PyIntObject;
    

    PyVarObject 대신 PyObject를 사용하기 때문에 struct에 ob_size 필드가 없으며 메모리 크기는 24 바이트로 제한됩니다. 8은 long 값, 8은 참조 카운트, 8은 type 객체 포인터입니다.

  2. ==============================

    2.longintrepr.h에서 우리는 파이썬 'int'객체가이 C 구조로 정의되어 있음을 알 수 있습니다 :

    longintrepr.h에서 우리는 파이썬 'int'객체가이 C 구조로 정의되어 있음을 알 수 있습니다 :

    struct _longobject {
            PyObject_VAR_HEAD
            digit ob_digit[1];
    };
    

    숫자는 부호없는 32 비트 값입니다. 공간의 대부분은 가변 크기 객체 헤더에 의해 사용됩니다. object.h에서 정의를 찾을 수 있습니다.

    typedef struct {
        PyObject ob_base;
        Py_ssize_t ob_size; /* Number of items in variable part */
    } PyVarObject;
    
    typedef struct _object {
        _PyObject_HEAD_EXTRA
        Py_ssize_t ob_refcnt;
        struct _typeobject *ob_type;
    } PyObject;
    

    우리는 64 비트 시스템을 가정 한 64 비트 Py_ssize_t를 사용하여 값에 "자릿수"의 수를 저장하는 것을 볼 수 있습니다. 이것은 아마도 낭비입니다. 일반 객체 헤더에는 64 비트 참조 카운트가 있고 객체 유형에 대한 포인터도 있으며 이는 64 비트 저장 영역이기도합니다. 참조 카운트는 Python이 객체를 할당 해제 할시기를 알아내는 데 필요합니다. 객체 유형에 대한 포인터는 C 구조가 유형을 테스트 할 수있는 방법이 없기 때문에 int가 아니라 문자열을 가지고 있음을 알기 위해 필요합니다. 임의의 포인터의 객체

    _PyObject_HEAD_EXTRA는 대부분의 Python 빌드에서 아무 것도 정의되지 않지만, 빌드가 해당 옵션을 가능하게하는 경우, 힙에있는 모든 Python 오브젝트의 링크 된 목록을 저장하는 데 사용될 수 있습니다. 각각 64 비트의 다른 두 포인터를 사용합니다.

  3. from https://stackoverflow.com/questions/23016610/why-do-ints-require-three-times-as-much-memory-in-python by cc-by-sa and MIT license