簡體   English   中英

將列表強制轉換為元組會導致元組有內存開銷嗎?

[英]Does casting a list into tuple result in tuple having memory overhead?

讓我們創建一個列表列表:

l = []
for i in range(1000000):
    l.append(['abcdefghijklmnopqrstuvwxyz', '1.8', '5', 'john@email.com', 'ffffffffff'])

l.__sizeof__()報告8697440進程占用111 MB

現在讓我們嘗試使用元組列表而不是列表列表:

l = []
for i in range(1000000):
    l.append(('abcdefghijklmnopqrstuvwxyz', '1.8', '5', 'john@email.com', 'ffffffffff'))

l.__sizeof__()報告8697440進程占用12 MB

如預期的那樣,巨大的進步。 現在讓我們在插入之前將列表轉換為元組:

l = []
for i in range(1000000):
    l.append(tuple(['abcdefghijklmnopqrstuvwxyz', '1.8', '5', 'john@email.com', 'ffffffffff']))

l.__sizeof__()報告8697440進程占用97 MB

為什么是97 MB,而不是12 MB?

是垃圾嗎? gc.collect()報告0

做一個del l釋放所有內存降到4 MB ,這只是一個小過一下空白解釋占據。 所以, l實際上是腫的。


當我們將列表轉換為元組時,與從頭開始創建的元組相比,生成的元組是否“不純正”?


如果是這樣,是否有解決方法將列表轉換為“純”元組?

簡短答案

不會您的推理方法存在缺陷,因為您沒有意識到tuple使用常量折疊
(提示:元組無法容納12MB的內容,而列表卻不能容納111MB的內容!)

長答案

您的第一個示例將創建一百萬個列表。 第三個示例創建一個列表和一百萬個元組。 輕微的內存差異是由於元組的存儲更為緊湊(例如,它們沒有任何額外的容量來處理追加)。

但是在第二個示例中,您有一個列表和一個元組-這是一個常量值,因此在代碼編譯期間會創建一次,並且在設置列表的每個元素時都將重用對該對象的引用。 如果它不是恆定的(例如,如果您將i用作元組的元素之一),則每次都必須創建一個新的元組,並且您將獲得與示例3相當的內存使用率。

第三個示例在理論上可以與#2具有相同的內存使用量,但是這將要求Python將每個新創建的元組與所有現有元組進行比較,以查看它們是否完全相同。 這將很慢,並且在不會創建大量相同元組的典型實際程序中,其收益極為有限。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM