Bagaimana daftar python disimpan dalam memori

Di CPython, elemen daftar disimpan sebagai penunjuk ke elemen, bukan nilai elemen itu sendiri. Ini terbukti dari yang mewakili daftar di C

// Fetched from CPython main branch. Removed comments for brevity. typedef struct { PyObject_VAR_HEAD PyObject **ob_item; /* Pointer reference to the element. */ Py_ssize_t allocated; }PyListObject;

Daftar kosong membangun from sys import getsizeof l = [] print(getsizeof(l)) _3 dan menggunakan sebagian memori

from sys import getsizeof l = [] print(getsizeof(l)) _

Ini kembali

56

Ukuran pasti dari daftar kosong dapat bervariasi di berbagai versi dan implementasi Python

Sebuah penunjuk tunggal ke suatu elemen membutuhkan 8 byte ruang dalam daftar. Setiap kali elemen tambahan ditambahkan ke daftar, Python secara dinamis mengalokasikan memori ekstra untuk mengakomodasi elemen di masa mendatang tanpa mengubah ukuran wadah. Ini menyiratkan, menambahkan satu elemen ke daftar kosong akan mendorong Python untuk mengalokasikan lebih banyak memori dari 8 byte

Mari kita uji ini dan tambahkan beberapa elemen ke daftar

# src.py from sys import getsizeof l = [] l.append(0) print(getsizeof(l)) _

Ini kembali

88

Tunggu, ukuran from sys import getsizeof l = [] print(getsizeof(l)) 4 seharusnya 64 byte (56+8) tetapi malah bertambah menjadi 88 byte. Ini terjadi karena dalam kasus ini, Python mengalokasikan 32 byte ekstra secara berlebihan untuk mengakomodasi elemen yang masuk di masa mendatang. Sekarang, jika Anda menambahkan 3 elemen lagi ke daftar, Anda akan melihat bahwa ukurannya tidak bertambah karena tidak ada alokasi ulang yang terjadi di sini

# src.py from sys import getsizeof l = [] l.append(0) l.append(1) l.append(2) l.append(3) print(getsizeof(l))

Ini mencetak

88

Menambahkan elemen kelima ke daftar di atas akan menambah ukuran daftar sebesar 32 byte (dapat berbeda dalam implementasi lain) lagi

# src.py from sys import getsizeof l = [] for i in range(6): l.append(l) print(getsizeof(l)) _

120

Alokasi memori dinamis ini membuat daftar sangat fleksibel, dan karena daftar hanya menyimpan referensi ke elemen, daftar dapat menampung objek yang heterogen tanpa masalah apa pun. Tetapi fleksibilitas untuk dapat menambahkan sejumlah elemen—tanpa peduli tentang alokasi memori—berakibat pada waktu eksekusi yang lebih lambat

Meskipun biasanya, Anda tidak perlu memikirkan untuk mengoptimalkan ini sama sekali, ada cara yang memungkinkan Anda melakukan pra-alokasi memori statis dalam daftar alih-alih membiarkan Python melakukan alokasi dinamis untuk Anda. Dengan cara ini, Anda dapat memastikan bahwa Python tidak perlu melakukan alokasi memori dinamis berkali-kali saat daftar Anda bertambah

Pra-alokasi statis akan membuat kode Anda sedikit lebih cepat. Saya harus melakukan ini sekali dalam loop bersarang ketat dan peningkatan kinerja 10% signifikan untuk layanan yang sedang saya kerjakan

Pra-alokasi memori dalam daftar

Mari mengukur kinerja menambahkan elemen ke daftar kosong. Saya menggunakan perintah from sys import getsizeof l = [] print(getsizeof(l)) 5 bawaan IPython untuk melakukannya

In [1]: %%timeit ...: ...: l=[] ...: for i in range(10_000): ...: l.append(i) ...: 499 µs ± 1.23 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

Sekarang, jika Anda mengetahui ukuran akhir dari daftar sebelumnya, maka Anda tidak perlu membuat daftar kosong dan menambahkan elemen ke dalamnya melalui sebuah loop. Anda dapat menginisialisasi daftar dengan from sys import getsizeof l = [] print(getsizeof(l)) _6 dan kemudian mengisi elemen seperti ini

from sys import getsizeof l = [] print(getsizeof(l)) _0

Ini sedikit lebih cepat dari cuplikan sebelumnya

from sys import getsizeof l = [] print(getsizeof(l)) _1

Tepung roti

Untuk kasus sederhana yang ditunjukkan di atas, pemahaman daftar akan menjadi sedikit lebih cepat daripada teknik pra-alokasi statis. Lihat diri mu sendiri

from sys import getsizeof l = [] print(getsizeof(l)) _2

Jadi, saya tidak menyarankan melakukan mikro-optimasi tanpa memperlengkapi kode Anda terlebih dahulu. Namun, pra-alokasi daftar masih bisa berguna dalam kasus yang lebih kompleks di mana Anda sudah mengetahui ukuran daftar akhir, dan memangkas beberapa mikrodetik membuat perbedaan yang cukup besar

Apakah daftar disimpan dalam memori?

Daftar, kemudian, disimpan dalam potongan memori yang berbeda yang ditautkan bersama dengan pointer, yang memungkinkan penggunaan memori yang efisien secara umum dan tidak memerlukan pengubahan ukuran. Ini juga memungkinkan manipulasi pointer yang mudah dan cepat saat mengubah daftar.

Bagaimana memori dikelola dalam daftar Python?

Seperti yang kita ketahui, Python menggunakan alokasi memori dinamis yang dikelola oleh struktur data Heap . Memory Heap menampung objek dan struktur data lain yang akan digunakan dalam program. Manajer memori Python mengelola alokasi atau de-alokasi ruang memori heap melalui fungsi API.

Bagaimana daftar disimpan secara internal Python?

Daftar Python secara internal direpresentasikan sebagai larik . Ide yang digunakan mirip dengan implementasi vektor di C++ atau ArrayList di Java. Operasi yang mahal adalah memasukkan dan menghapus item di awal (karena semuanya harus dipindahkan). Memasukkan di bagian akhir juga menjadi mahal jika ruang yang dialokasikan sebelumnya menjadi penuh.

Apakah daftar Python disimpan secara bersebelahan dalam memori?

Seperti yang telah ditunjukkan oleh Greg Hewgill, daftar python menggunakan blok memori yang berdekatan untuk mempercepat pengindeksan. Anda dapat menggunakan deque jika Anda menginginkan karakteristik kinerja dari daftar tertaut.

Postingan terbaru

LIHAT SEMUA