Seperti yang kita sedia maklum, Python bukanlah bahasa yang cekap. Di samping itu, gelung adalah operasi yang sangat memakan masa dalam mana-mana bahasa. Jika mana-mana operasi satu langkah mudah mengambil 1 unit masa, jika operasi ini diulang berpuluh ribu kali, masa akhir yang dibelanjakan juga akan meningkat puluhan ribu kali.
sementara dan untuk ialah dua kata kunci yang biasa digunakan untuk melaksanakan gelung dalam Python Sebenarnya terdapat jurang dalam kecekapan operasinya. Contohnya, kod ujian berikut:
import timeit def while_loop(n=100_000_000): i = 0 s = 0 semasa saya < s += i i += 1 pulangan s def for_loop(n=100_000_000): s = 0 untuk i dalam julat(n): s += i pulangan s def utama(): print('while looptt', timeit.timeit(while_loop, number=1)) print('for looptt', timeit.timeit(for_loop, number=1)) jika __nama__ == '__utama__': utama() # => gelung manakala 4.718853999860585 # => untuk gelung 3.211570399813354
Ini ialah operasi jumlah mudah yang mengira hasil tambah semua nombor asli daripada 1 hingga n. Anda boleh melihat bahawa gelung for adalah 1.5 saat lebih cepat daripada sementara.
Perbezaan utama terletak pada mekanisme berbeza antara keduanya.
Dalam setiap gelung, semasa sebenarnya melakukan dua langkah lebih daripada untuk: semakan sempadan dan pembolehubah kenaikan i. Iaitu, setiap kali gelung dilaksanakan, while akan melakukan semakan sempadan (semasa i < n) dan pengiraan kenaikan (i +=1). Kedua-dua langkah adalah kod Python tulen yang jelas.
Gelung for tidak perlu melakukan operasi semakan had dan kenaikan, dan tidak menambah kod Python eksplisit (kod Python tulen kurang cekap daripada kod C yang mendasari). Apabila bilangan kitaran cukup besar, jurang kecekapan yang ketara muncul.
Anda boleh menambah dua lagi fungsi untuk menambah semakan sempadan dan pengiraan kenaikan yang tidak perlu dalam gelung for:
import timeit def while_loop(n=100_000_000): i = 0 s = 0 semasa saya < s += i i += 1 pulangan s def for_loop(n=100_000_000): s = 0 untuk i dalam julat(n): s += i pulangan s def for_loop_with_inc(n=100_000_000): s = 0 untuk i dalam julat(n): s += i i += 1 pulangan s def for_loop_with_test(n=100_000_000): s = 0 untuk i dalam julat(n): jika saya < lulus s += i pulangan s def utama(): print('while looptt', timeit.timeit(while_loop, number=1)) print('for looptt', timeit.timeit(for_loop, number=1)) print('untuk gelung dengan incrementtt', timeit.timeit(for_loop_with_inc, number=1)) print('for loop with testtt', timeit.timeit(for_loop_with_test, number=1)) jika __nama__ == '__utama__': utama() # => gelung manakala 4.718853999860585 # => untuk gelung 3.211570399813354 # => untuk gelung dengan kenaikan4.602369500091299 # => untuk gelung dengan ujian 4.18337869993411
Dapat dilihat bahawa semakan sempadan tambahan dan operasi kenaikan automatik telah banyak mempengaruhi kecekapan pelaksanaan gelung.
Seperti yang dinyatakan sebelum ini, penterjemah asas Python dan fungsi terbina dalam dilaksanakan dalam bahasa C. Kecekapan pelaksanaan bahasa C jauh lebih besar daripada Python.
import timeit def while_loop(n=100_000_000): i = 0 s = 0 semasa saya < s += i i += 1 pulangan s def for_loop(n=100_000_000): s = 0 untuk i dalam julat(n): s += i pulangan s def sum_range(n=100_000_000): jumlah pulangan(julat(n)) def utama(): print('while looptt', timeit.timeit(while_loop, number=1)) print('for looptt', timeit.timeit(for_loop, number=1)) print('jumlah julat', timeit.timeit(julat_jumlah, nombor=1)) jika __nama__ == '__utama__': utama() # => gelung manakala 4.718853999860585 # => untuk gelung 3.211570399813354 # => julat jumlah0.8658821999561042
Ia boleh dilihat bahawa selepas menggunakan jumlah fungsi terbina dalam untuk menggantikan gelung, kecekapan pelaksanaan kod telah meningkat dua kali ganda.
Operasi pengumpulan jumlah fungsi terbina dalam sebenarnya adalah gelung, tetapi ia dilaksanakan dalam bahasa C, manakala operasi jumlah dalam gelung for dilakukan oleh Python tulen kod s += saya sedar. C > Python.
Perluaskan pemikiran anda. Kita semua telah dewasa mendengar cerita tentang pengiraan bijak Gauss pada masa kanak-kanak tentang jumlah nombor 1 hingga 100.Jumlah 1…100 adalah bersamaan dengan (1 + 100) * 50. Kaedah pengiraan ini juga boleh digunakan untuk operasi penjumlahan di atas.
import timeit def while_loop(n=100_000_000): i = 0 s = 0 semasa saya < s += i i += 1 pulangan s def for_loop(n=100_000_000): s = 0 untuk i dalam julat(n): s += i pulangan s def sum_range(n=100_000_000): jumlah pulangan(julat(n)) def math_sum(n=100_000_000): kembali (n * (n - 1)) // 2 def utama(): print('while looptt', timeit.timeit(while_loop, number=1)) print('for looptt', timeit.timeit(for_loop, number=1)) print('jumlah julat', timeit.timeit(julat_jumlah, nombor=1)) print('math sumtt', timeit.timeit(math_sum, number=1)) jika __nama__ == '__utama__': utama() # => gelung manakala 4.718853999860585 # => untuk gelung 3.211570399813354 # => julat jumlah0.8658821999561042 # => jumlah matematik 2.400018274784088e-06Masa pelaksanaan akhir jumlah matematik ialah kira-kira 2.4e-6, yang dipendekkan berjuta-juta kali. Idea di sini ialah kerana kecekapan gelung adalah rendah, sekeping kod perlu dilaksanakan ratusan juta kali.
Cuma jangan gelung dan gunakan formula matematik untuk menjadikan ratusan juta operasi gelung menjadi satu langkah sahaja. Kecekapan secara semula jadi telah dipertingkatkan berbanding sebelum ini.
Kesimpulan akhir (sedikit Riddler):
Cara terpantas untuk melaksanakan gelung - - — ——Hanya jangan gunakan gelung
Untuk Python, gunakan fungsi terbina dalam sebanyak mungkin untuk meminimumkan kod Python tulen dalam gelung.
Atas ialah kandungan terperinci Kaedah Python gelung yang paling cepat boleh menjejaskan pemahaman anda!. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!