亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Python整數對象實現原理詳解

系統 2301 0

整數對象在Python內部用PyIntObject結構體表示:

            
typedef struct {
PyObject_HEAD
long ob_ival;
} PyIntObject;
          

PyObject_HEAD宏中定義的兩個屬性分別是:

            
int ob_refcnt; 
struct _typeobject *ob_type;
          

這兩個屬性是所有Python對象固有的:

  • ob_refcnt:對象的引用計數,與Python的內存管理機制有關,它實現了基于引用計數的垃圾收集機制
  • ob_type:用于描述Python對象的類型信息。

由此看來PyIntObject就是一個對C語言中long類型的數值的擴展,出于性能考慮,對于小整數,Python使用小整數對象池small_ints緩存了[-5,257)之間的整數,該范圍內的整數在Python系統中是共享的。

            
#define NSMALLPOSINTS 257
#define NSMALLNEGINTS 5
static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
          


Python整數對象實現原理詳解_第1張圖片

而超過該范圍的整數即使值相同,但對象不一定是同一個,如下所示:當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對象時,能夠通過free_list快速獲得所需的內存。

Python整數對象實現原理詳解_第2張圖片

創建一個整數對象時,如果它在小整數范圍內,就直接從小整數緩沖池中直接返回,如果不在該范圍內,就開辟一個大整數緩沖池內存空間:

            
[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創建成功后,free_list表頭就指向了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_list的呢?這個秘密放在了整數對象垃圾回收的時候,在PyIntObject對象的tp_dealloc操作中可以看到:

            
[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使用,進而將free_list表頭指向了這個要被銷毀的對象上。

總結

  • Python中的int對象就是c語言中long類型數值的擴展
  • 小整數對象[-5, 257]在python中是共享的
  • 整數對象都是從緩沖池中獲取的。
  • 整數對象回收時,內存并不會歸還給系統,而是將其對象的ob_type指向free_list,供新創建的整數對象使用

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 91福利影院 | 国产综合精品一区二区 | 在线中文字幕网 | 国产国语一级毛片中文 | 四虎4hu影库永久地址 | 免费福利小视频 | 久久久精品视频免费观看 | 最新中文字幕在线播放 | 蘑菇视频绿巨人小黄鸭 | 精品一区二区三区中文字幕 | 天天爽夜夜爽天天做夜夜做 | 欧美伊人久久 | 国产精品欧美久久久久天天影视 | 五月开心婷婷 | 操久在线 | 图片专区亚洲 欧美 另类 | 成人小视频免费 | 97在线观免费视频观看 | 毛片免费看看 | 深夜成人影院 | 日本毛片在线 | 四虎最新地址 | 久久免费精品 | 欧美国产中文 | 四虎4hu影库免费永久国产 | 精品综合久久久久久97超人 | 日日日日人人人夜夜夜2017 | 欧美一二三区视频 | 国内精品久久影院 | 国产成人mv在线观看入口视频 | 一级理论片 | 尤物视频在线观看视频 | 欧美日韩亚洲国产精品一区二区 | 波多野结衣一区二区三区在线观看 | 国产成人午夜性a一级毛片 国产成人午夜性视频影院 国产成人系列 | 亚洲视频 中文字幕 | 久久综合激情 | 四虎国产精品永久地址51 | 狠狠的操你 | 国产成人福利 | 免费一级a毛片免费观看欧美大片 |