现在的位置: 首页 > 综合 > 正文

Python中整数对象的实现

2018年03月22日 ⁄ 综合 ⁄ 共 1623字 ⁄ 字号 评论关闭

理解Python中的整数对象的实现,有助于我们了解Python的对象系统。在此记下这几天的阅读内容。

PyIntObject是一个结构体,由一个PyObjec_HEAD和int ob_ival组成,如下:

typedef struct {
    PyObject_HEAD
    long ob_ival;
} PyIntObject;

而PyObject_HEAD这个结构体中又有两个字段:int ref引用计数器,struct _typeobject * ob_type表示类型的指针。

Python整数类型分为小整数和大整数,对于频繁使用的小整数,采用引用计数方式,相同的值共享同一块内存,是在python初始化时就分配好了的。

一般为-5~257,可以自己调整。对于这其中的数, 完全缓存。

#ifndef NSMALLPOSINTS
#define NSMALLPOSINTS           257
#endif
#ifndef NSMALLNEGINTS
#define NSMALLNEGINTS           5
#endif
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
/* References to small integers are saved in this array so that they
   can be shared.
   The integers that are saved are those in the range
   -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
*/
static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
#endif

对于大整数,则是使用PyIntBlock结构,实现单相列表,将内存链接起来,使用的时候,就从free_list里取出一块。

#define BLOCK_SIZE      1000    /* 1K less typical malloc overhead */
#define BHEAD_SIZE      8       /* Enough for a 64-bit pointer */
#define N_INTOBJECTS    ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyIntObject))

struct _intblock {
    struct _intblock *next;
    PyIntObject objects[N_INTOBJECTS];
};

typedef struct _intblock PyIntBlock;

static PyIntBlock *block_list = NULL;
static PyIntObject *free_list = NULL;

当然,del一个大整数对象的时候,并不是将内存归还给系统,而是加入到自由链表中。

最后,我们来看一看整数对象的创建:

PyObject *
PyInt_FromLong(long ival)
{
    register PyIntObject *v;
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
    if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) {
        v = small_ints[ival + NSMALLNEGINTS];
        Py_INCREF(v);
#ifdef COUNT_ALLOCS
        if (ival >= 0)
            quick_int_allocs++;
        else
            quick_neg_int_allocs++;
#endif
        return (PyObject *) v;
    }
#endif
    if (free_list == NULL) {
        if ((free_list = fill_free_list()) == NULL)
            return NULL;
    }
    /* Inline PyObject_New */
    v = free_list;
    free_list = (PyIntObject *)Py_TYPE(v);
    PyObject_INIT(v, &PyInt_Type);
    v->ob_ival = ival;
    return (PyObject *) v;
}
【上篇】
【下篇】

抱歉!评论已关闭.