[英]Does reusing a list slice to get length cost additional memory?
我在這個答案的評論中提出了一些建議。 馬丁·彼得斯(Martijn Pieters)說,我的建議會占用大量內存,他通常是對的,但是我喜歡自己看看事情,所以我嘗試介紹一下。 這是我得到的:
#!/usr/bin/env python
""" interpolate.py """
from memory_profiler import profile
@profile
def interpolate1(alist):
length = (1 + len(alist)) // 2
alist[::2] = [0] * length
@profile
def interpolate2(alist):
length = len(alist[::2])
alist[::2] = [0] * length
a = []
b = []
for i in range(5, 9):
print i
exp = 10**i
a[:] = range(exp)
b[:] = range(exp)
interpolate1(a)
interpolate2(b)
我看不到切片解決方案的內存成本有任何增量差異,但是有時我看到的是算術解決方案。 以exp = 7
的結果為例:
7
Filename: interpolate.py
Line # Mem usage Increment Line Contents
================================================
5 750.1 MiB 0.0 MiB @profile
6 def interpolate1(alist):
7 750.1 MiB 0.0 MiB length = (1 + len(alist)) // 2
8 826.4 MiB 76.3 MiB alist[::2] = [0] * length
Filename: interpolate.py
Line # Mem usage Increment Line Contents
================================================
10 826.4 MiB 0.0 MiB @profile
11 def interpolate2(alist):
12 826.4 MiB 0.0 MiB length = len(alist[::2])
13 826.4 MiB 0.0 MiB alist[::2] = [0] * length
我嘗試了一些其他的方法來分析,包括運行interpolate2
前 interpolate1
,隨機運行秩序,以及更小的名單,但結果相當一致。
我可以假設結果是因為無論哪種方式都為列表切片分配了內存,無論是在賦值的右側還是左側,但是以任何方式對其進行切片,看起來切片的解決方案即使使用算術運算也會中斷解。 我是否正確解釋了這些結果?
是的,將為僅為slice創建的新列表對象保留額外的內存。
但是,查詢長度后,列表對象再次被丟棄 。 您剛剛創建了一個列表對象,只是為了計算一個列表的一半長度。
內存分配相對昂貴,即使您隨后再次丟棄該對象也是如此。 當您正在尋找永久性的內存占用增加時,這就是我所指的成本 。 無論列表對象可能是瞬態的,您仍然需要為此對象分配內存。
使用timeit
比較這兩種方法時,成本立即顯而易見:
>>> import timeit
>>> def calculate(alist):
... (1 + len(alist)) // 2
...
>>> def allocate(alist):
... len(alist[::2])
...
>>> testlist = range(10**5)
>>> timeit.timeit('f(testlist)', 'from __main__ import testlist, calculate as f', number=10000)
0.003368854522705078
>>> timeit.timeit('f(testlist)', 'from __main__ import testlist, allocate as f', number=10000)
2.7687110900878906
切片僅需創建一個列表對象並跨引用的一半進行復制,但是該操作所花的時間是簡單地從現有列表中計算長度的800倍 。
注意,我實際上不得不減少timeit
重復計數; 默認的100萬次重復將需要額外的4.5分鍾。 我不會等那么久,而直接計算只花了0.18秒。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.