[英]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.