Saya mengerti konsep apa yang timeit
dilakukan tetapi saya tidak yakin bagaimana mengimplementasikannya dalam kode saya.
Bagaimana saya bisa membandingkan dua fungsi, katakan insertion_sort
dan tim_sort
, dengan timeit
?
Cara timeit bekerja adalah dengan menjalankan kode pengaturan sekali dan kemudian membuat panggilan berulang ke serangkaian pernyataan. Jadi, jika Anda ingin menguji penyortiran, diperlukan kehati-hatian agar satu pass pada in-place sort tidak mempengaruhi pass berikutnya dengan data yang sudah diurutkan (yang, tentu saja, akan membuat Timsort benar-benar bersinar karena berkinerja terbaik. ketika data sudah dipesan sebagian).
Berikut adalah contoh cara menyiapkan tes untuk penyortiran:
>>> import timeit
>>> setup = '''
import random
random.seed('slartibartfast')
s = [random.random() for i in range(1000)]
timsort = list.sort
'''
>>> print min(timeit.Timer('a=s[:]; timsort(a)', setup=setup).repeat(7, 1000))
0.334147930145
Perhatikan bahwa rangkaian pernyataan membuat salinan baru dari data yang tidak disortir pada setiap pass.
Juga, perhatikan teknik pengaturan waktu menjalankan rangkaian pengukuran tujuh kali dan hanya menjaga waktu terbaik - ini benar-benar dapat membantu mengurangi distorsi pengukuran karena proses lain yang berjalan pada sistem Anda.
Itulah tips saya untuk menggunakan timeit dengan benar. Semoga ini membantu :-)
timsort(a)
dan ambil perbedaan :-).repeat(7,1000)
sudah melakukan ini (dengan menggunakan benih yang sama)! Jadi solusi Anda adalah IMO yang sempurna..repeat(7, 1000)
vs.repeat(2, 3500)
vs.repeat(35, 200
) harus bergantung pada bagaimana kesalahan karena beban sistem dibandingkan dengan kesalahan karena variabilitas input. Dalam kasus ekstrem jika sistem Anda selalu di bawah beban berat, dan Anda melihat ekor tipis panjang di sebelah kiri distribusi waktu eksekusi (ketika Anda menangkapnya dalam keadaan idle langka), Anda bahkan mungkin menemukan.repeat(7000,1)
lebih berguna daripada.repeat(7,1000)
jika Anda tidak dapat menganggarkan lebih dari 7000 berjalan.Jika Anda ingin menggunakan
timeit
sesi Python interaktif, ada dua opsi yang mudah:Gunakan shell IPython . Ini fitur
%timeit
fungsi khusus yang nyaman :Dalam juru bahasa Python standar, Anda dapat mengakses fungsi dan nama lain yang Anda tentukan sebelumnya selama sesi interaktif dengan mengimpornya dari
__main__
dalam pernyataan pengaturan:sumber
from __main__ import f
tekniknya. Saya tidak berpikir ini dikenal secara luas sebagaimana mestinya. Ini berguna dalam kasus-kasus seperti ini di mana panggilan fungsi atau metode sedang diatur waktunya. Dalam kasus lain (mengatur serangkaian langkah), ini kurang membantu karena memperkenalkan overhead panggilan fungsi.%timeit f(x)
sys._getframe(N).f_globals
) seharusnya menjadi default dari awal.Saya akan memberi Anda rahasia: cara terbaik untuk menggunakan
timeit
adalah di baris perintah.Di baris perintah,
timeit
lakukan analisis statistik yang tepat: ini memberi tahu Anda berapa lama waktu yang paling singkat. Ini bagus karena semua kesalahan dalam pengaturan waktu adalah positif. Jadi waktu tersingkat memiliki kesalahan paling sedikit di dalamnya. Tidak ada cara untuk mendapatkan kesalahan negatif karena komputer tidak pernah dapat menghitung lebih cepat daripada yang bisa dihitung!Jadi, antarmuka baris perintah:
Itu cukup sederhana, eh?
Anda dapat mengatur barang-barang:
yang bermanfaat juga!
Jika Anda ingin banyak baris, Anda bisa menggunakan kelanjutan otomatis shell atau menggunakan argumen terpisah:
Itu memberikan pengaturan
dan waktu
Jika Anda ingin memiliki skrip yang lebih panjang, Anda mungkin tergoda untuk pindah ke
timeit
dalam skrip Python. Saya sarankan menghindari itu karena analisis dan pengaturan waktu hanya lebih baik di baris perintah. Sebaliknya, saya cenderung membuat skrip shell:Ini bisa memakan waktu sedikit lebih lama karena beberapa inisialisasi, tetapi biasanya itu bukan masalah besar.
Tetapi bagaimana jika Anda ingin menggunakan
timeit
di dalam modul Anda?Nah, cara sederhana adalah melakukan:
dan itu memberi Anda waktu kumulatif ( bukan minimum!) untuk menjalankan jumlah itu.
Untuk mendapatkan analisis yang baik, gunakan
.repeat
dan ambil minimum:Anda biasanya harus menggabungkan ini dengan
functools.partial
bukannyalambda: ...
menurunkan overhead. Dengan demikian Anda dapat memiliki sesuatu seperti:Anda juga dapat melakukan:
yang akan memberi Anda sesuatu yang lebih dekat ke antarmuka dari command-line, tetapi dengan cara yang jauh lebih keren. The
"from __main__ import ..."
memungkinkan Anda menggunakan kode dari modul utama Anda dalam lingkungan buatan yang dibuat olehtimeit
.Perlu dicatat bahwa ini adalah pembungkus yang nyaman
Timer(...).timeit(...)
dan karenanya tidak terlalu bagus dalam hal waktu. Saya pribadi jauh lebih suka menggunakanTimer(...).repeat(...)
seperti yang saya tunjukkan di atas.Peringatan
Ada beberapa peringatan dengan
timeit
yang menahan di mana-mana.Overhead tidak diperhitungkan. Katakan Anda ingin waktu
x += 1
, untuk mengetahui berapa lama penambahan:Yah, ini bukan 0,0476 μs. Anda hanya tahu bahwa itu kurang dari itu. Semua kesalahan adalah positif.
Jadi cobalah dan temukan overhead murni :
Itu overhead 30% baik hanya dari waktu! Ini secara besar-besaran dapat mengubah pengaturan waktu relatif. Tetapi Anda hanya benar-benar peduli tentang penambahan waktu; timing pencarian untuk
x
juga perlu dimasukkan dalam overhead:Perbedaannya tidak jauh lebih besar, tetapi ada di sana.
Metode bermutasi berbahaya.
Tapi itu sama sekali salah!
x
adalah daftar kosong setelah iterasi pertama. Anda harus menginisialisasi ulang:Tetapi kemudian Anda memiliki banyak overhead. Akun untuk itu secara terpisah.
Perhatikan bahwa mengurangi overhead adalah wajar di sini hanya karena overhead adalah sebagian kecil dari waktu.
Sebagai contoh Anda, perlu dicatat bahwa kedua Sisipan Penyisipan dan Tim Mengurutkan memiliki perilaku waktu yang sama sekali tidak biasa untuk daftar yang sudah diurutkan. Ini berarti Anda akan memerlukan
random.shuffle
antara macam-macam jika Anda ingin menghindari merusak waktu Anda.sumber
timeit
dari suatu program tetapi berfungsi dengan cara yang sama seperti baris perintah? .timeit
jalankanpass
pernyataan ketika tidak ada argumen yang diberikan, yang tentu saja membutuhkan waktu. Jika ada argumen yang diberikan, tidakpass
akan dieksekusi, jadi kurangi beberapa usecs dari setiap waktu akan salah.0.014
Jika Anda ingin membandingkan dua blok kode / fungsi dengan cepat yang dapat Anda lakukan:
sumber
Saya menemukan cara termudah untuk menggunakan timeit adalah dari baris perintah:
Diberikan test.py :
jalankan timeit seperti ini:
sumber
bagi saya, ini adalah cara tercepat:
sumber
sumber
Ini sangat bagus:
sumber
memungkinkan pengaturan kamus yang sama di masing-masing berikut dan menguji waktu eksekusi.
Argumen pengaturan pada dasarnya adalah mengatur kamus
Nomor untuk menjalankan kode 1000000 kali. Bukan pengaturan tetapi stmt
Ketika Anda menjalankan ini, Anda dapat melihat bahwa indeks jauh lebih cepat daripada mendapatkan. Anda dapat menjalankannya beberapa kali untuk melihatnya.
Kode ini pada dasarnya mencoba untuk mendapatkan nilai c dalam kamus.
Inilah hasil saya, hasil Anda akan berbeda.
berdasarkan indeks: 0.20900007452246427
oleh get: 0.54841166886888
sumber
cukup kirimkan seluruh kode Anda sebagai argumen timeit:
sumber
sumber
gc.enable()
?Modul timeit bawaan berfungsi paling baik dari baris perintah IPython.
Fungsi waktu dari dalam modul:
sumber
Contoh cara menggunakan interpreter Python REPL dengan fungsi yang menerima parameter.
sumber
Anda akan membuat dua fungsi dan menjalankan sesuatu yang mirip dengan ini. Perhatikan, Anda ingin memilih jumlah eksekusi / lari yang sama untuk membandingkan apel dengan apel.
Ini diuji dengan Python 3.7.
Berikut adalah kode untuk kemudahan menyalinnya
sumber