Python 정수 대상 실현 원리 상세 설명
typedef struct {
PyObject_HEAD
long ob_ival;
} PyIntObject;
PyObject_HEAD 매크로 에서 정의 하 는 두 속성 은 다음 과 같 습 니 다.
int ob_refcnt;
struct _typeobject *ob_type;
이 두 속성 은 모든 Python 대상 의 고유 한 것 입 니 다.
#define NSMALLPOSINTS 257
#define NSMALLNEGINTS 5
static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
이 범 위 를 초과 한 정 수 는 값 이 같 더 라 도 대상 이 꼭 같은 것 은 아니다.다음 과 같다.a 와 b 의 값 이 모두 10000 이지 만 같은 대상 이 아니 라 값 이 1 일 때 a 와 b 는 같은 대상 에 속한다.
>>> a = 10000
>>> b = 10000
>>> print a is b
False
>>> a = 1
>>> b = 1
>>> print a is b
True
[-5,257)사 이 를 초과 한 다른 정수 에 대해 Python 역시 전문 적 인 버퍼 를 제공 하여 이른바 큰 정수 로 사용 할 수 있 도록 제공 하여 매번 사용 할 때마다 끊임없이 malloc 분배 메모리 가 가 져 오 는 효율 적 인 손실 을 피한다.이 메모리 공간 은 PyIntBlock 입 니 다.
struct _intblock {
struct _intblock *next;
PyIntObject objects[N_INTOBJECTS];
};
typedef struct _intblock PyIntBlock;
static PyIntBlock *block_list = NULL;
static PyIntObject *free_list = NULL;
이 메모리 블록(PyIntBlock)은 단 방향 링크 를 통 해 구성 되 어 있 으 며,표 두 는 Block 입 니 다.list,표 두 는 항상 새로 만 든 PyIntBlock 대상 을 가리 키 고 있 습 니 다.PyIntBlock 은 두 가지 속성 이 있 습 니 다:next,objects.next 포인터 가 다음 PyIntBlock 대상 을 가리 키 고 있 습 니 다.objects 는 PyIntObject 배열(최종 적 으로 단 방향 링크 로 바 뀔 것 입 니 다)입 니 다.캐 시 된 PyIntObjet 대상 을 저장 하 는 메모리 공간 입 니 다.
free_list 단 방향 링크 는 모든 PyIntBlock 메모리 블록 에 남 은 메모리 입 니 다.모든 남 은 메모리 가 하나의 링크 를 통 해 구 성 된 장점 은 Python 이 새로운 메모리 가 필요 할 때 새로운 PyIntObject 대상 을 저장 할 때 freelist 필요 한 메모 리 를 빠르게 가 져 옵 니 다.
정수 대상 을 만 들 때 작은 정수 범위 내 에 있 으 면 작은 정수 버퍼 에서 바로 돌아 갑 니 다.이 범위 내 에 있 지 않 으 면 큰 정수 버퍼 메모리 공간 을 엽 니 다.
[intobject.c]
PyObject* PyInt_FromLong(long ival)
{
register PyIntObject *v;
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
//[1] :
if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) {
v = small_ints[ival + NSMALLNEGINTS];
Py_INCREF(v);
return (PyObject *) v;
}
#endif
//[2] :
if (free_list == NULL) {
if ((free_list = fill_free_list()) == NULL)
return NULL;
}
//[3] : (inline) PyObject_New
v = free_list;
free_list = (PyIntObject *)v->ob_type;
PyObject_INIT(v, &PyInt_Type);
v->ob_ival = ival;
return (PyObject *) v;
}
fill_free_list 는 큰 정수 버퍼 메모리 공간 을 만 드 는 논리 입 니 다.이 함 수 는 free 를 되 돌려 줍 니 다.list 링크,정수 대상 ival 생 성 성공 후 freelist 헤더 가 v->ob 를 가리 키 고 있 습 니 다.type,ob_type 은 모든 Python 대상 에서 형식 정 보 를 표시 하 는 필드 가 아 닙 니까?왜 여기 서 연결 지침 으로 하나 요?이것 은 Python 이 성능 과 코드 의 우아 함 사이 에서 중용의 도 를 취하 고 이름 의 남용 으로 유형 안전 에 대한 견 지 를 포기 한 것 이다.다음 PyIntObject 를 가리 키 는 지침 으로 이해 하면 됩 니 다.
[intobject.c]
static PyIntObject* fill_free_list(void)
{
PyIntObject *p, *q;
// sizeof(PyIntBlock)
// block list PyIntBlock
p = (PyIntObject *) PyMem_MALLOC(sizeof(PyIntBlock));
((PyIntBlock *)p)->next = block_list;
block_list = (PyIntBlock *)p;
//: PyIntBlock PyIntObject (objects)
p = &((PyIntBlock *)p)->objects[0];
q = p + N_INTOBJECTS;
while (--q > p)
// ob_type PyIntObject。
q->ob_type = (struct _typeobject *)(q-1);
q->ob_type = NULL;
return p + N_INTOBJECTS - 1;
}
서로 다른 PyIntBlock 의 남 은 메모리 가 어떻게 연결 되 어 free 를 구성 하 는 지리스트 는 요?이 비밀 은 정수 대상 쓰레기 회수 시 PyIntObject 대상 tpdealloc 작업 중 볼 수 있 는 것:
[intobject.c]
static void int_dealloc(PyIntObject *v)
{
if (PyInt_CheckExact(v)) {
v->ob_type = (struct _typeobject *)free_list;
free_list = v;
}
else
v->ob_type->tp_free((PyObject *)v);
}
원래 PyIntObject 대상 이 소각 되 었 을 때 사용 하 는 메모리 가 방출 되 지 않 고 Python 에 의 해 계속 사용 되 어 freelist 헤더 가 삭 제 될 대상 을 가리 키 고 있 습 니 다.총결산
파 이 썬 의 int 대상 은 c 언어 에서 long 형식 수치의 확장 입 니 다
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
로마 숫자를 정수로 또는 그 반대로 변환그 중 하나는 로마 숫자를 정수로 변환하는 함수를 만드는 것이었고 두 번째는 그 반대를 수행하는 함수를 만드는 것이었습니다. 문자만 포함합니다'I', 'V', 'X', 'L', 'C', 'D', 'M' ; 문자열이 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.