Berikut ini adalah pedoman kasar dan tebakan berdasarkan pengalaman. Kamu harustimeit
atau profil kasus penggunaan konkret Anda untuk mendapatkan angka keras, dan angka-angka itu kadang-kadang mungkin tidak setuju dengan di bawah ini.
Pemahaman daftar biasanya sedikit lebih cepat daripada for
loop yang sama persis (yang sebenarnya membangun daftar), kemungkinan besar karena tidak harus mencari daftar dan append
metode pada setiap iterasi. Namun, pemahaman daftar masih melakukan loop tingkat-bytecode:
>>> dis.dis(<the code object for `[x for x in range(10)]`>)
1 0 BUILD_LIST 0
3 LOAD_FAST 0 (.0)
>> 6 FOR_ITER 12 (to 21)
9 STORE_FAST 1 (x)
12 LOAD_FAST 1 (x)
15 LIST_APPEND 2
18 JUMP_ABSOLUTE 6
>> 21 RETURN_VALUE
Menggunakan pemahaman daftar di tempat loop itu tidak membangun daftar, secara tidak masuk akal mengumpulkan daftar nilai yang tidak berarti dan kemudian membuang daftar itu, seringkali lebih lambat karena overhead menciptakan dan memperluas daftar. Pemahaman daftar bukan sihir yang secara inheren lebih cepat daripada loop lama yang baik.
Adapun fungsi pemrosesan daftar fungsional: Meskipun ini ditulis dalam C dan mungkin mengungguli fungsi setara yang ditulis dengan Python, mereka tidak selalu merupakan opsi tercepat. Beberapa percepatan diharapkan jika fungsi tersebut ditulis dalam C juga. Tetapi kebanyakan kasus menggunakan alambda
(atau fungsi Python lainnya), overhead berulang kali mengatur frame tumpukan Python dll memakan penghematan. Cukup melakukan pekerjaan in-line yang sama, tanpa pemanggilan fungsi (mis. Pemahaman daftar alih-alih map
atau filter
) seringkali sedikit lebih cepat.
Misalkan dalam game yang saya kembangkan saya perlu menggambar peta yang rumit dan besar menggunakan untuk loop. Pertanyaan ini pasti relevan, karena jika pemahaman daftar, misalnya, memang lebih cepat, itu akan menjadi pilihan yang jauh lebih baik untuk menghindari keterlambatan (Meskipun kompleksitas visual dari kode).
Kemungkinannya adalah, jika kode seperti ini belum cukup cepat ketika ditulis dengan Python non-"baik" yang baik, tidak ada jumlah optimasi mikro tingkat Python akan membuatnya cukup cepat dan Anda harus mulai berpikir untuk menjatuhkan ke C. Sementara luas optimasi mikro sering dapat mempercepat kode Python, ada batas rendah (dalam hal absolut) untuk ini. Selain itu, bahkan sebelum Anda mencapai langit-langit itu, menjadi lebih hemat biaya (percepatan 15% vs 300% dengan upaya yang sama) untuk menggigit peluru dan menulis beberapa huruf C.
Anda bertanya secara spesifik tentang
map()
,filter()
danreduce()
, tetapi saya berasumsi Anda ingin tahu tentang pemrograman fungsional secara umum. Setelah menguji ini sendiri pada masalah jarak komputasi antara semua titik dalam satu set poin, pemrograman fungsional (menggunakanstarmap
fungsi dariitertools
modul built-in ) ternyata sedikit lebih lambat daripada for-loop (mengambil 1,25 kali lebih lama, dalam fakta). Berikut ini contoh kode yang saya gunakan:Apakah versi fungsional lebih cepat daripada versi prosedural?
sumber
Saya menulis naskah sederhana yang menguji kecepatan dan inilah yang saya temukan. Sebenarnya untuk loop adalah yang tercepat dalam kasus saya. Itu benar-benar mengejutkan saya, lihat di bawah (sedang menghitung jumlah kotak).
sumber
int
insquare_sum4
juga membuatnya sedikit lebih cepat dan hanya sedikit lebih lambat daripada for loop.Saya memodifikasi kode @ Alisa dan digunakan
cProfile
untuk menunjukkan mengapa pemahaman daftar lebih cepat:Inilah hasilnya:
MENURUT OPINI SAYA:
reduce
danmap
secara umum cukup lambat. Tidak hanya itu, penggunaansum
pada iterator yangmap
dikembalikan lambat, dibandingkansum
dengan daftarfor_loop
menggunakan append, yang tentu saja lambat sampai batas tertentusum
lebih cepat, berbeda denganmap
sumber
Menambahkan twist pada jawaban Alphii , sebenarnya for loop akan menjadi yang terbaik kedua dan sekitar 6 kali lebih lambat daripada
map
Perubahan utama adalah untuk menghilangkan
sum
panggilan lambat , serta mungkin tidak perluint()
dalam kasus terakhir. Menempatkan for for dan map dalam istilah yang sama membuatnya menjadi fakta, sebenarnya. Ingat bahwa lambda adalah konsep fungsional dan secara teori seharusnya tidak memiliki efek samping, tetapi, well, mereka dapat memiliki efek samping seperti menambahkana
. Hasil dalam hal ini dengan Python 3.6.1, Ubuntu 14.04, Intel (R) Core (TM) i7-4770 CPU @ 3.40GHzsumber
Saya telah berhasil memodifikasi beberapa kode @ alpiii dan menemukan bahwa pemahaman Daftar sedikit lebih cepat daripada untuk loop. Mungkin disebabkan oleh
int()
, tidak adil antara pemahaman daftar dan untuk loop.sumber