日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python源码剖析-笔记2

發布時間:2023/12/10 python 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python源码剖析-笔记2 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
  • PyStringObject對象

    typedef struct {PyObject_VAR_HEADlong ob_shash;int ob_sstate;char ob_sval[1]; } PyStringObject;

    頭部保存一個ob_size,表示字符串在內存中的具體長度,字符串由ob_sval指針指向,但是,字符串的最后一位也一定是’\0’結束,由于有ob_size的標記,允許字符串中間也有’\0’字符的存在。

  • 字符串的類型對象中,tp_itemsize設置為sizeof(char),這個值表示變長對象中每個元素單位的長度,每一個python中的變長對象(string、list等),都需要在對應的類型對象中設置tp_itemsize的值。tp_itemsize和ob_size共同決定了一個對象需要在內存中實際占用的空間大小。

  • 對于空字符串,python會返回其內部的nullstring對象,避免每次都創建,這個對象相當于是共享的。

  • Intern機制。為了避免每次為相同的字符串開創新對象,可以利用Intern機制來實現。相當于創建時會先查找是否有使用了Intern機制創建的對象,包含的字符串和待創建的一樣,如果存在,則直接返回該對象的引用,而不用再次創建一個全新的對象。

  • interned的實現,實際上是維護了一個map<PyObject*, PyObject*>的字典集合,key,value都是那個采用Interned機制的Py對象指針,如果在這個map中找到一個對象的字符串內容和待創建的一致,則直接把待創建的指針指向這個map的value。加入Map時,按照py的引用計數規則,對應的對象引用計數會先+1,相當于這個對象引用+2了,這樣的話,這種對象實際不可能出現引用為0的情況,所有,對于加入到Interned中的對象,會在加入完畢后執行引用計數-2的操作。

  • 對于單個字符的,也有一個靜態緩沖區,類似PyIntObject對小整數的處理。

  • PyListObject類似于c++中的vector

  • 結構定義:

    typedef struct {PyObject_VAR_HEADPyObject **ob_item;int allocated;} PyListObject;

    一次分配的內存是大于現實需要的內存,類似vector的內存分配策略。
    0 <= ob_size <= allocated;
    len(list) == ob_size

  • append的元素會放在ob_size位置上,所以內部元素的內存空間不一定連續,但是邏輯上是連續的

  • PyList的對象緩沖池。 在每個PyList被銷毀的那會,會檢測free_list這個緩沖池是否滿了,如果沒滿,則會把當前這個待銷毀的對象放入這個緩沖池中。當然,這個List內部的元素item都是要被free掉內存的,不然就是一堆野指針了。只是這個對象的內存空間會被緩存下來,避免下次的再次申請內存導致額外的消耗。

  • PyDictObject底層采用hash_table來存儲,hash沖突利用開放地址法來解決(lookdict方法來搜索元素)。

  • dict里面每個pair對都是一個PyDictEntry

    typedef struct {long me_hash; /* cached hash code of me_key */PyObject *me_key;PyObject *me_value;} PyDictEntry;

    每個dict內部都有一個PyDictEntry的小規模數組(默認8),當dict的size小于8時,內部標識的ma_table指針就指向這個小數組,如果大于8,則申請一塊大內存,ma_table指向那塊內存。me_key有三種狀態,dummy、unused和實際有效使用的active。刪除元素后會變成dummy狀態,freeslot指針會指向該位置,freeslot在下次插入新元素時會使用到。

  • 搜索時根據hash值查找,如果查到的key和待搜索的不同,則根據lookdict二次探測。

  • dict每次的插入,會調用PyDict_SetItem,在這里面會先計算hash值,hash = PyObject_Hash(PyObject*)。在最后,會根據裝載率來決定當前ma_table指向的內存是否需要擴容,因為裝載率高了,hash沖突的概率就會加大。

  • PyDict使用的緩沖池技術和Int這些類似,都是在一個Object銷毀時加入到緩沖池中。

  • 總結

    以上是生活随笔為你收集整理的python源码剖析-笔记2的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。