最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python?虛擬機字典dict內存優(yōu)化方法解析

 更新時間:2023年03月26日 08:49:03   作者:一無是處的研究僧  
這篇文章主要為大家介紹了Python?虛擬機字典dict內存優(yōu)化方法解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

在前面的文章當中我們討論的是 python3 當中早期的內嵌數據結構字典的實現,在本篇文章當中主要介紹在后續(xù)對于字典的內存優(yōu)化。

字典優(yōu)化

在前面的文章當中我們介紹的字典的數據結構主要如下所示:

typedef struct {
    PyObject_HEAD
    Py_ssize_t ma_used;
    PyDictKeysObject *ma_keys;
    PyObject **ma_values;
} PyDictObject;
struct _dictkeysobject {
    Py_ssize_t dk_refcnt;
    Py_ssize_t dk_size;
    dict_lookup_func dk_lookup;
    Py_ssize_t dk_usable;
    PyDictKeyEntry dk_entries[1];
};
typedef struct {
    /* Cached hash code of me_key. */
    Py_hash_t me_hash;
    PyObject *me_key;
    PyObject *me_value; /* This field is only meaningful for combined tables */
} PyDictKeyEntry;

用圖示的方式表示如下圖所示:

所有的鍵值對都存儲在 dk_entries 數組當中,比如對于 "Hello" "World" 這個鍵值對存儲過程如下所示,如果 "Hello" 的哈希值等于 8 ,那么計算出來對象在 dk_entries 數組當中的下標位 0 。

在前面的文章當中我們談到了,在 cpython 當中 dk_entries 數組當中的一個對象占用 24 字節(jié)的內存空間,在 cpython 當中的負載因子是 23\frac{2}{3}32? 。而一個 entry 的大小是 24 個字節(jié),如果 dk_entries 的長度是 1024 的話,那么大概有 1024 / 3 * 24 = 8K 的內存空間是浪費的。為了解決這個問題,在新版的 cpython 當中采取了一個策略用于減少內存的使用。具體的設計如下圖所示:

在新的字典當中 cpython 對于 dk_entries 來說如果正常的哈希表的長度為 8 的話,因為負載因子是 23\frac{2}{3}32? 真正給 dk_entries 分配的長度是 5 = 8 / 3,那么現在有一個問題就是如何根據不同的哈希值進行對象的存儲。dk_indices 就是這個作用的,他的長度和真正的哈希表的長度是一樣的,dk_indices 是一個整型數組這個數組保存的是要保存對象在 dk_entries 當中的下標,比如在上面的例子當中 dk_indices[7] = 0,就表示哈希值求余數之后的值等于 7,0 表示對象在 dk_entries 當中的下標。

現在我們再插入一個數據 "World" "Hello" 鍵值對,假設 "World" 的哈希值等于 8,那么對哈希值求余數之后等于 0 ,那么 dk_indices[0] 就是保存對象在 dk_entries 數組當中的下標的,圖中對應的下標為 1 (因為 dk_entries 數組當中的每個數據都要使用,因此直接遞增即可,下一個對象來的話就保存在 dk_entries 數組的第 3 個(下標為 2)位置)。

內存分析

首先我們先來分析一下數組 dk_indices 的數據類型,在 cpython 的內部實現當中并沒有一刀切的直接將這個數組當中的數據類型設置成 int 類型。

dk_indices 數組主要有以下幾個類型:

  • 當哈希表長度小于 0xff 時,dk_indices 的數據類型為 int8_t ,即一個元素值占一個字節(jié)。
  • 當哈希表長度小于 0xffff 時,dk_indices 的數據類型為 int16_t ,即一個元素值占 2 一個字節(jié)。
  • 當哈希表長度小于 0xffffffff 時,dk_indices 的數據類型為 int32_t ,即一個元素值占 4 個字節(jié)。
  • 當哈希表長度大于 0xffffffff 時,dk_indices 的數據類型為 int64_t ,即一個元素值占 8 個字節(jié)。

與這個相關的代碼如下所示:

/* lookup indices.  returns DKIX_EMPTY, DKIX_DUMMY, or ix >=0 */
static inline Py_ssize_t
dictkeys_get_index(const PyDictKeysObject *keys, Py_ssize_t i)
{
    Py_ssize_t s = DK_SIZE(keys);
    Py_ssize_t ix;
    if (s <= 0xff) {
        const int8_t *indices = (const int8_t*)(keys->dk_indices);
        ix = indices[i];
    }
    else if (s <= 0xffff) {
        const int16_t *indices = (const int16_t*)(keys->dk_indices);
        ix = indices[i];
    }
#if SIZEOF_VOID_P > 4
    else if (s > 0xffffffff) {
        const int64_t *indices = (const int64_t*)(keys->dk_indices);
        ix = indices[i];
    }
#endif
    else {
        const int32_t *indices = (const int32_t*)(keys->dk_indices);
        ix = indices[i];
    }
    assert(ix >= DKIX_DUMMY);
    return ix;
}

現在來分析一下相關的內存使用情況:

哈希表長度能夠保存的鍵值對數目老版本新版本節(jié)約內存量(字節(jié))
256256 * 2 / 3 = 17024 * 256 = 61441 * 256 + 24 * 170 = 43361808
6553665536 * 2 / 3 = 4369024 * 65536 = 15728642 * 65536 + 24 * 43690 = 1179632393232

從上面的表格我們可以看到哈希表的長度越大我們節(jié)約的內存就越大,優(yōu)化的效果就越明顯。

總結

在本篇文章當中主要介紹了在 python3 當中對于字典的優(yōu)化操作,主要是通過一個內存占用量比較小的數組去保存鍵值對在真實保存鍵值對當中的下標實現的,這個方法對于節(jié)約內存的效果是非常明顯的。

本篇文章是深入理解 python 虛擬機系列文章之一,

文章地址:github.com/Chang-LeHun…

更多精彩內容合集可訪問項目:github.com/Chang-LeHun…

以上就是Python 虛擬機字典dict的優(yōu)化方法解析的詳細內容,更多關于Python 虛擬機字典dict優(yōu)化的資料請關注腳本之家其它相關文章!

相關文章

  • 解決Python調用df.to_csv()出現中文亂碼的問題

    解決Python調用df.to_csv()出現中文亂碼的問題

    在Python使用df.to_csv()時,若出現中文亂碼,可通過加入參數encoding="utf_8_sig"解決,"utf-8"編碼不包含BOM,直接處理文件時會將BOM誤讀為內容;而"utf_8_sig"會識別并處理BOM,避免亂碼,此方法為實踐經驗,供參考
    2024-09-09
  • python2.7的flask框架之引用js&css等靜態(tài)文件的實現方法

    python2.7的flask框架之引用js&css等靜態(tài)文件的實現方法

    今天小編就為大家分享一篇python2.7的flask框架之引用js&css等靜態(tài)文件的實現方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-08-08
  • 使用Python對文件進行批量改名的方法

    使用Python對文件進行批量改名的方法

    這篇文章主要介紹了使用Python對文件進行批量改名的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • 淺談Python3多線程之間的執(zhí)行順序問題

    淺談Python3多線程之間的執(zhí)行順序問題

    這篇文章主要介紹了淺談Python3多線程之間的執(zhí)行順序問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-05-05
  • 了解不常見但是實用的Python技巧

    了解不常見但是實用的Python技巧

    下面有一些相對不常見但非常有用的Python技巧,小編來和大家一起學習一下
    2019-05-05
  • 在Django的View中使用asyncio的方法

    在Django的View中使用asyncio的方法

    這篇文章主要介紹了在Django的View中使用asyncio的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-07-07
  • Pytorch 抽取vgg各層并進行定制化處理的方法

    Pytorch 抽取vgg各層并進行定制化處理的方法

    今天小編就為大家分享一篇Pytorch 抽取vgg各層并進行定制化處理的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-08-08
  • VSCode配置Anaconda Python環(huán)境的實現

    VSCode配置Anaconda Python環(huán)境的實現

    VisualStudioCode中可以使用Anaconda環(huán)境進行Python開發(fā),本文主要介紹了VSCode配置Anaconda Python環(huán)境的實現,具有一定的參考價值,感興趣的可以了解一下
    2025-03-03
  • Python?Pygame實現可控制的煙花游戲

    Python?Pygame實現可控制的煙花游戲

    大家好,本篇文章主要講的是Python?Pygame實現可控制的煙花游戲,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • keras 實現輕量級網絡ShuffleNet教程

    keras 實現輕量級網絡ShuffleNet教程

    這篇文章主要介紹了keras 實現輕量級網絡ShuffleNet教程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-06-06

最新評論

芦山县| 六安市| 华宁县| 台南市| 长垣县| 井冈山市| 舟曲县| 略阳县| 平昌县| 博兴县| 广饶县| 泰顺县| 新郑市| 香格里拉县| 三门峡市| 太和县| 凌云县| 酉阳| 闵行区| 卢氏县| 密云县| 阳高县| 饶河县| 新泰市| 镇宁| 宣化县| 阳曲县| 修武县| 星子县| 潢川县| 长乐市| 石狮市| 逊克县| 城市| 图们市| 福清市| 通州区| 祁连县| 盐亭县| 土默特右旗| 大丰市|