Apakah ada perbedaan kinerja antara tupel dan daftar ketika datang ke instantiation dan pengambilan elemen?
python
performance
list
tuples
python-internals
Hanya baca
sumber
sumber
Jawaban:
The
dis
modul disassembles kode byte untuk fungsi dan berguna untuk melihat perbedaan antara tupel dan daftar.Dalam hal ini, Anda dapat melihat bahwa mengakses elemen menghasilkan kode yang identik, tetapi menetapkan tuple jauh lebih cepat daripada menetapkan daftar.
sumber
ListLike
dengan__getitem__
yang melakukan sesuatu yang sangat lambat, lalu bongkarx = ListLike((1, 2, 3, 4, 5)); y = x[2]
. Bytecode akan lebih seperti contoh tuple di atas daripada contoh daftar, tetapi apakah Anda benar-benar percaya itu berarti kinerja akan serupa?Secara umum, Anda mungkin mengharapkan tuple menjadi sedikit lebih cepat. Namun Anda harus menguji kasus spesifik Anda (jika perbedaannya mungkin berdampak pada kinerja program Anda - ingat "optimasi prematur adalah akar dari semua kejahatan").
Python membuatnya sangat mudah: timeit adalah teman Anda.
dan...
Jadi dalam kasus ini, instantiasi hampir merupakan urutan besarnya lebih cepat untuk tuple, tetapi akses item sebenarnya agak lebih cepat untuk daftar! Jadi, jika Anda membuat beberapa tupel dan mengaksesnya berkali-kali, mungkin sebenarnya lebih cepat menggunakan daftar.
Tentu saja jika Anda ingin mengubah item, daftar pasti akan lebih cepat karena Anda harus membuat tuple baru untuk mengubah satu item (karena tuple tidak dapat diubah).
sumber
python -m timeit "x=tuple(xrange(999999))"
vspython -m timeit "x=list(xrange(999999))"
. Seperti yang diduga, butuh waktu lebih lama untuk mematerialisasi tuple daripada daftar.-s "SETUP_CODE"
dijalankan sebelum kode waktu aktual.Ringkasan
Tuples cenderung berkinerja lebih baik daripada daftar di hampir setiap kategori:
1) Tuples dapat dilipat secara konstan .
2) Tuples dapat digunakan kembali alih-alih disalin.
3) Tuple kompak dan tidak mengalokasikan berlebihan.
4) Tuples mereferensikan elemen mereka secara langsung.
Tuples dapat dilipat secara konstan
Tupel konstanta dapat dihitung dengan pengoptimal lubang pengintai Python atau pengoptimal AST. Daftar, di sisi lain, bisa dibangun dari awal:
Tuples tidak perlu disalin
Menjalankan
tuple(some_tuple)
kembali segera dengan sendirinya. Karena tupel tidak dapat diubah, mereka tidak harus disalin:Sebaliknya,
list(some_list)
mengharuskan semua data untuk disalin ke daftar baru:Tuples tidak mengalokasikan secara berlebihan
Karena ukuran tuple ditetapkan, ia dapat disimpan lebih kompak daripada daftar yang perlu dialokasikan berlebihan untuk membuat operasi append () lebih efisien.
Ini memberi tuple keuntungan ruang yang bagus:
Berikut adalah komentar dari Objects / listobject.c yang menjelaskan apa yang dilakukan daftar:
Tuples merujuk langsung ke elemen mereka
Referensi ke objek digabungkan secara langsung dalam objek tuple. Sebaliknya, daftar memiliki lapisan tipuan ekstra ke array eksternal pointer.
Ini memberi tuple keuntungan kecepatan kecil untuk pencarian yang diindeks dan dibongkar:
Ini adalah bagaimana tuple
(10, 20)
disimpan:Berikut cara penyimpanan daftar
[10, 20]
:Perhatikan bahwa objek tuple menggabungkan dua pointer data secara langsung sementara objek daftar memiliki lapisan tipuan tambahan ke array eksternal yang memegang dua pointer data.
sumber
Internally, tuples are stored a little more efficiently than lists, and also tuples can be accessed slightly faster.
Bagaimana Anda bisa menjelaskan hasil dari jawaban dF.tuple(some_tuple)
hanya mengembalikansome_tuple
sendiri jikasome_tuple
hashable — ketika isinya secara kekal berubah dan hashable. Jika tidak,tuple(some_tuple)
kembalikan tuple baru. Misalnya, ketikasome_tuple
berisi item yang bisa diubah.Tuples, yang tidak berubah, lebih hemat memori; daftar, untuk efisiensi, memori keseluruhan untuk memungkinkan menambahkan tanpa
realloc
s konstan . Jadi, jika Anda ingin beralih melalui urutan konstan nilai dalam kode Anda (misalnyafor direction in 'up', 'right', 'down', 'left':
), tupel lebih disukai, karena tupel seperti itu telah dihitung sebelumnya dalam waktu kompilasi.Kecepatan akses harus sama (keduanya disimpan sebagai array yang bersebelahan dalam memori).
Tapi,
alist.append(item)
lebih disukaiatuple+= (item,)
ketika Anda berurusan dengan data yang bisa berubah. Ingat, tupel dimaksudkan untuk diperlakukan sebagai catatan tanpa nama bidang.sumber
Anda juga harus mempertimbangkan
array
modul di perpustakaan standar jika semua item dalam daftar atau tupel Anda memiliki tipe C yang sama. Ini akan memakan sedikit memori dan bisa lebih cepat.sumber
Berikut ini adalah patokan kecil lain, hanya demi itu ..
Mari kita rata-rata ini:
Anda dapat menyebutnya hampir tidak meyakinkan.
Tetapi tentu saja, tuple mengambil
101.239%
waktu, atau1.239%
waktu ekstra untuk melakukan pekerjaan dibandingkan dengan daftar.sumber
Tuple harus sedikit lebih efisien dan karena itu, lebih cepat, daripada daftar karena mereka tidak berubah.
sumber
Alasan utama Tuple menjadi sangat efisien dalam membaca adalah karena itu tidak berubah.
Mengapa objek yang tidak dapat diubah mudah dibaca?
Alasannya tuple dapat disimpan dalam cache memori, tidak seperti daftar. Program selalu membaca dari daftar lokasi memori karena dapat berubah (dapat berubah sewaktu-waktu).
sumber