เห็นได้ชัดว่าlist(a)
ไม่รวม overallocate, [x for x in a]
overallocates ในบางจุดและ[*a]
overallocates ตลอดเวลา ?
นี่คือขนาด n จาก 0 ถึง 12 และขนาดผลลัพธ์เป็นไบต์สำหรับวิธีการสามวิธี:
0 56 56 56
1 64 88 88
2 72 88 96
3 80 88 104
4 88 88 112
5 96 120 120
6 104 120 128
7 112 120 136
8 120 120 152
9 128 184 184
10 136 184 192
11 144 184 200
12 152 184 208
คำนวณแบบนี้สามารถทำซ้ำได้ที่ repl.itโดยใช้ Python 3 8 :
from sys import getsizeof
for n in range(13):
a = [None] * n
print(n, getsizeof(list(a)),
getsizeof([x for x in a]),
getsizeof([*a]))
ดังนั้นมันทำงานอย่างไร อย่างไร[*a]
overallocate? จริงๆแล้วมันใช้กลไกอะไรในการสร้างรายการผลลัพธ์จากอินพุตที่กำหนด? มันใช้ตัววนซ้ำa
และใช้บางอย่างเช่นlist.append
? ซอร์สโค้ดอยู่ที่ไหน
( Colab ที่มีข้อมูลและรหัสที่สร้างภาพ)
ซูมเข้าสู่ n ที่เล็กกว่า:
ซูมออกไปใหญ่กว่า n:
list(a)
ดำเนินการทั้งหมดใน C; มันสามารถจัดสรรโหนดบัฟเฟอร์ภายในโหนดเป็นมัน iterates a
กว่า [x for x in a]
ใช้LIST_APPEND
จำนวนมากดังนั้นจึงเป็นไปตามรูปแบบ "overallocate เล็กน้อยปกติจัดสรรใหม่เมื่อจำเป็น" ของรายการปกติ [*a]
การใช้BUILD_LIST_UNPACK
งานที่ ... ฉันไม่รู้ว่าจะทำอะไรนอกเหนือจากที่เห็นได้ชัดว่าจัดสรรเกินตลอดเวลา :)
list(a)
และ[*a]
เหมือนกันและมีทั้ง overallocate เปรียบเทียบกับ[x for x in a]
ดังนั้น ... sys.getsizeof
อาจไม่ใช่เครื่องมือที่เหมาะสมที่จะใช้ที่นี่
sys.getsizeof
เป็นเครื่องมือที่ถูกต้องมันแค่แสดงให้เห็นว่าlist(a)
เคยใช้ใน อันที่จริงมีอะไรใหม่ในหลาม 3.8กล่าวถึงมัน"ตัวสร้างรายการไม่ overallocate [ ... ]"
[*a]
ปรากฏขึ้นในการทำงานเช่นเดียวกับที่ใช้extend
ในรายการที่ว่างเปล่า