一.python中的整數物件
1.首先補充一下c語言知識的盲點,python底層都是用c寫的,看的時候發現自己還是有**看不懂,所有就先複習一下這些知識點。
先說明 c語言中register關鍵字的作用
register修飾符暗示編譯程式相應的變數將被頻繁地使用,如果可能的話,應將其儲存在cpu的暫存器中,以加快其儲存速度。例如下面的記憶體塊拷貝**,
還有就是關於引數巨集的一些用法,之前c大學學的都是無參巨集,這兩者雖然在原理上是一樣的,但是有參巨集其中的陷阱比較多。
巨集定義的缺點:
由於是直接嵌入的,所以**可能相對多一點;
巢狀定義過多可能會影響程式的可讀性,而且很容易出錯,不容易除錯。
對帶參的巨集而言,由於是直接替換,並不會檢查引數是否合法,存在安全隱患。
2.小整數物件,物件池
實際的程式設計中,數值比較小的整數,比如1,2,29可能在程式中會非常頻繁的使用,但是由於python的特性,這些小整數物件都在堆上,要不斷的malloc,free會很浪費效能。所以使用了物件池技術。那什麼叫小整數呢,這個可以由寫**的你自己決定。但是非常麻煩,你需要去修改python的源**。在python原始碼中
#ifndef nsmallposints
#define nsmallposints 257
#endif
#ifndef nsmallposints
#define nsmallnegints 5
#endif
#if nsmallnegints + nsmallposints >0
static pyobject *small_ints[nsmallnegints + nsmallposints]
#endif
small_ints就是物件池,或者說 pyintobject池。在python 2.5中,將小整數集的範圍預設設定為 (-5,257)。對於小整數集會存放在記憶體中,並將其指標存放於small_ints中。
3.大整數物件
python會提供一塊記憶體空間供大整數物件輪流使用,也就是說誰需要的時候就用誰。在python中,有乙個pyintblock結構,在這個結構的基礎上,實現了的乙個單向列表。
#define block_size 100
#define bhead_size 8
#define n_intobjects ((block_size-bheadsize) / sizeof(pyintobject))
struct _intblock (
struct _intblock *next;
pyintobject object[n_intobjects];
);typedf struct _intblock pyintblock;
static pyintblock *block_list =null
static pyintobject *free_list =null
這段**的意思就是結構裡維護了一塊記憶體(block),其中儲存了一些pyintobject物件。從pyintblock的定義中可以看到,維護著n_intobjects個物件,當然這裡的值我們也可以修改python的源**去改變這個值。pyintblock的單向列表由block_list維護,每乙個block都維護乙個pyintobject物件的記憶體。而free_list則維護全部block的空閒記憶體。
4.整數物件的銷毀
static void int_dealloc(pyintobject *v)
( if (pyint_checkexact(v))
else
v->obtype->tp_free((pyobject *)v);
由block_list維護的pyintblock鍊錶中的記憶體實際是所有的大整數物件共同分享的。當乙個pyintobject物件被銷毀時,它所佔的記憶體並不會被釋放,歸還給系統,python會繼續保留著。將來提供給別的pyintobject使用,所以python應該將其鏈入了free_list所維護的自由記憶體鍊錶。 【注】: 實線是block_list, 虛線是free_list
由於python記憶體共享,python用於實現該物件池的記憶體與歷史上建立的整數物件的個數無關,而僅僅與同一時刻共存的的整數物件個數的最大值有關。
5.小整數物件池的初始化
現在只剩下最後乙個問題了,在small_ints中,它維護的只是pyintobject指標,那這些小整數物件是什麼時候被建立和初始化的呢,完成這一系列的操作正是_pyint_init
int _pyint_init(void)
python原始碼剖析 筆記2
pystringobject物件 typedef struct pystringobject 頭部儲存乙個ob size,表示字串在記憶體中的具體長度,字串由ob sval指標指向,但是,字串的最後一位也一定是 0 結束,由於有ob size的標記,允許字串中間也有 0 字元的存在。字串的型別物件中...
iptables原始碼分析(2)
1.1 表的查詢 再回到iptc init 函式上來,它根據表名,從核心獲取對應的表的相關資訊,handle是乙個iptc handle t型別的指標,在libiptc.c中,有如下定義 transparent handle type.typedef struct iptc handle iptc ...
Leveldb原始碼分析 2
輕鬆一刻,前面約定中講過leveldb使用了很多varint型編碼,典型的如後面將涉及到的各種key。其中的編碼 解碼函式分為varint和fixedint兩種。int32和int64操作都是類似的。首先是fixedint編碼,直接上 很簡單明瞭。void encodefixed32 char bu...