欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

Python中整數(shù)對(duì)象的原理是什么

Python中整數(shù)對(duì)象的原理是什么,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。

創(chuàng)新互聯(lián)主營(yíng)烏魯木齊網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,成都App制作,烏魯木齊h5微信小程序搭建,烏魯木齊網(wǎng)站營(yíng)銷推廣歡迎烏魯木齊等地區(qū)企業(yè)咨詢

整數(shù)對(duì)象在Python內(nèi)部用PyIntObject結(jié)構(gòu)體表示:

typedef struct {
    PyObject_HEAD
    long ob_ival;
} PyIntObject;

PyObject_HEAD宏中定義的兩個(gè)屬性分別是:

int ob_refcnt;        
struct _typeobject *ob_type;

這兩個(gè)屬性是所有Python對(duì)象固有的:

  • ob_refcnt:對(duì)象的引用計(jì)數(shù),與Python的內(nèi)存管理機(jī)制有關(guān),它實(shí)現(xiàn)了基于引用計(jì)數(shù)的垃圾收集機(jī)制

  • ob_type:用于描述Python對(duì)象的類型信息。

由此看來(lái)PyIntObject就是一個(gè)對(duì)C語(yǔ)言中l(wèi)ong類型的數(shù)值的擴(kuò)展,出于性能考慮,對(duì)于小整數(shù),Python使用小整數(shù)對(duì)象池small_ints緩存了[-5,257)之間的整數(shù),該范圍內(nèi)的整數(shù)在Python系統(tǒng)中是共享的。

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

超過該范圍的整數(shù)即使值相同,但對(duì)象不一定是同一個(gè),如下所示:a與b的值都是10000,但并不是同一個(gè)對(duì)象,值都是1是,他們屬于同一個(gè)對(duì)象。

>>> a = 10000
>>> b = 10000
>>> print a is b
False
>>> a = 1
>>> b = 1
>>> print a is b
True

對(duì)于超出了[-5, 257)之間的其他整數(shù),Python同樣提供了專門的緩沖池,供這些所謂的大整數(shù)使用,避免每次使用的時(shí)候都要不斷的malloc分配內(nèi)存帶來(lái)的效率損耗。這塊內(nèi)存空間就是PyIntBlock。

struct _intblock {

    struct _intblock *next;
    PyIntObject objects[N_INTOBJECTS];
};
typedef struct _intblock PyIntBlock;

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

這些內(nèi)存塊(blocks)由一個(gè)單向鏈表表示,表頭是block_list,block_list始終指向最新創(chuàng)建的PyIntBlock對(duì)象。next指針指向下一個(gè)PyIntBlock對(duì)象,objects是一個(gè)PyIntObject數(shù)組(最終會(huì)轉(zhuǎn)變成單向鏈表),它是真正用于存儲(chǔ)被緩存的PyIntObjet對(duì)象的內(nèi)存空間。 free_list單向鏈表是所有block的objects中空閑的內(nèi)存。所有空閑內(nèi)存通過一個(gè)鏈表組織起來(lái)的好處就是在Python需要新的內(nèi)存來(lái)存儲(chǔ)新的PyIntObject對(duì)象時(shí),能夠通過free_list快速獲得所需的內(nèi)存。

Python中整數(shù)對(duì)象的原理是什么

創(chuàng)建一個(gè)整數(shù)對(duì)象時(shí),如果它在小整數(shù)范圍內(nèi),就直接從小整數(shù)緩沖池中直接返回,如果不在該范圍內(nèi),就開辟一個(gè)大整數(shù)緩沖池內(nèi)存空間:

[intobject.c]
PyObject* PyInt_FromLong(long ival)
{
     register PyIntObject *v; 
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
     //[1] :嘗試使用小整數(shù)對(duì)象池
     if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) {
        v = small_ints[ival + NSMALLNEGINTS];
        Py_INCREF(v);
        return (PyObject *) v;
    }
#endif
    //[2] :為通用整數(shù)對(duì)象池申請(qǐng)新的內(nèi)存空間
    if (free_list == NULL) {
        if ((free_list = fill_free_list()) == NULL)
            return NULL;
    }
    //[3] : (inline)內(nèi)聯(lián)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就是創(chuàng)建大整數(shù)緩沖池內(nèi)存空間的邏輯,該函數(shù)返回一個(gè)free_list鏈表,當(dāng)整數(shù)對(duì)象ival創(chuàng)建成功后,free_list表頭就指向了v->ob_type,ob_type不是所有Python對(duì)象中表示類型信息的字段嗎?怎么在這里作為一個(gè)連接指針呢?這是Python在性能與代碼優(yōu)雅之間取中庸之道,對(duì)名稱的濫用,放棄了對(duì)類型安全的堅(jiān)持。把它理解成指向下一個(gè)PyIntObject的指針即可。

[intobject.c]
static PyIntObject* fill_free_list(void)
{
    PyIntObject *p, *q;
    // 申請(qǐng)大小為sizeof(PyIntBlock)的內(nèi)存空間,并鏈接到已有的block list中
    // block list使用指向最新創(chuàng)建的PyIntBlock
    p = (PyIntObject *) PyMem_MALLOC(sizeof(PyIntBlock));
    ((PyIntBlock *)p)->next = block_list;
    block_list = (PyIntBlock *)p;

    //:將PyIntBlock中的PyIntObject數(shù)組——objects——轉(zhuǎn)變成單向鏈表
    p = &((PyIntBlock *)p)->objects[0];
    q = p + N_INTOBJECTS;
    while (--q > p)
        // ob_type指向下一個(gè)未被使用的PyIntObject。
        q->ob_type = (struct _typeobject *)(q-1);
    q->ob_type = NULL;
    return p + N_INTOBJECTS - 1;
}

不同的PyIntBlock里面的空閑的內(nèi)存是怎樣連接起來(lái)構(gòu)成free_list的呢?這個(gè)秘密放在了整數(shù)對(duì)象垃圾回收的時(shí)候,在PyIntObject對(duì)象的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);
}

原來(lái)PyIntObject對(duì)象銷毀時(shí),它所占用的內(nèi)存并不會(huì)釋放,而是繼續(xù)被Python使用,進(jìn)而將free_list表頭指向了這個(gè)要被銷毀的對(duì)象上。

總結(jié)
  • Python中的int對(duì)象就是c語(yǔ)言中l(wèi)ong類型數(shù)值的擴(kuò)展

  • 小整數(shù)對(duì)象[-5, 257]在python中是共享的

  • 整數(shù)對(duì)象都是從緩沖池中獲取的。

  • 整數(shù)對(duì)象回收時(shí),內(nèi)存并不會(huì)歸還給系統(tǒng),而是將其對(duì)象的obtype指向freelist,供新創(chuàng)建的整數(shù)對(duì)象使用

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。

網(wǎng)站名稱:Python中整數(shù)對(duì)象的原理是什么
網(wǎng)頁(yè)鏈接:http://aaarwkj.com/article48/igejep.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作、外貿(mào)建站、建站公司、自適應(yīng)網(wǎng)站、網(wǎng)頁(yè)設(shè)計(jì)公司、

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站建設(shè)
欧美亚洲另类日韩综合网| 久久夜色精品亚洲国产| 中文字幕一区侵犯人妻| 成人午夜福利视频大全| 麻豆人妻少妇精品系列| 人人妻人人澡人人爽的视频| 激情影院在线观看福利| 国产成人综合亚洲欧美在线| 欧美av一区二区三区四区| 99精品久久久中文字幕日本| 人妻少妇亚洲精品视频| 男人的天堂av免费看看| 97在线资源视频播放| 久亚洲精品九九久久99| 国产高清不卡av在线| 久热视频这里只有精品99| 亚洲一二三无人区是什么| 欧美国产日韩二区一区在线| 亚洲一区二区三区有码| 蜜臀久久精品国产综合| 91国语对白在线观看| 日韩免费黄色av网站| 四虎在线观看最新免费| 午夜香蕉av一区二区三区| 久久人妻少妇嫩草av蜜桃综合| 少妇被又粗又硬猛烈进视频| 国产日产精品久久婷婷色| 一区二区不卡日韩av| 亚洲午夜精品理论在线不卡| 欧美精品亚洲精品国产| 欧美日韩国产另类久久| 国产成人久久久精品一区| 欧洲亚洲国产一区二区| 日本精品中文字幕人妻| 日本束缚人妻一区二区三区| 国产一区二区三区av在线播放| 人妖激情一区二区三区| 国产三级av高清一区二区| 久久亚洲综合精品少妇| 国产精品美女黄色av| 亚洲第一精品国产日韩|