Bagaimana bisa kau profil Python script?
Project Euler dan lainnya coding kontes sering memiliki waktu maksimal untuk menjalankan atau orang-orang yang membanggakan seberapa cepat mereka solusi tertentu berjalan. Dengan python, kadang-kadang pendekatan yang agak kludgey - yaitu, menambahkan waktu kode untuk __main__
.
Apa adalah cara yang baik untuk profil berapa lama python program yang diperlukan untuk menjalankan?
1198
26
Python termasuk profiler disebut cProfile. Tidak hanya memberikan total waktu berjalan, tetapi juga kali setiap fungsi secara terpisah, dan memberitahu anda berapa banyak setiap kali fungsi dipanggil, sehingga mudah untuk menentukan di mana anda harus melakukan optimasi.
Anda dapat memanggil dari dalam kode anda, atau dari penerjemah, seperti ini:
Bahkan lebih berguna, anda dapat memanggil cProfile ketika menjalankan script:
Untuk membuatnya bahkan lebih mudah, saya membuat sedikit batch file yang bernama 'profil.bat':
Jadi semua harus saya lakukan adalah menjalankan:
Dan saya mendapatkan ini:
EDIT: Update link ke video yang baik sumber daya dari PyCon 2013 yang berjudul Python Profiling [Juga via YouTube](https://www.youtube.com/watch?v=QJwVYlDzAXs).
Beberapa waktu lalu saya membuat
pycallgraph
yang menghasilkan visualisasi dari kode Python. Edit: I've diperbarui contoh untuk bekerja dengan 3.3, rilis terbaru seperti tulisan ini.Setelah
pip menginstal pycallgraph
dan menginstal GraphViz anda dapat menjalankannya dari baris perintah:Atau, anda dapat profil bagian-bagian tertentu dari kode anda:
Salah satu dari ini akan menghasilkan
pycallgraph.png
file yang mirip dengan gambar di bawah ini:It's worth menunjukkan bahwa menggunakan profiler hanya bekerja (secara default) di thread utama, dan anda tidak't mendapatkan informasi dari thread lain jika anda menggunakan mereka. Hal ini dapat menjadi sedikit gotcha seperti itu adalah benar-benar tidak disebutkan dalam profiler dokumentasi.
Jika anda juga ingin profil benang, anda'll ingin melihat
threading.setprofile()
fungsi di docs.Anda juga bisa membuat sendiri
threading.Thread
subclass untuk melakukannya:dan gunakan itu
ProfiledThread
kelas bukan satu standar. Hal ini mungkin memberi anda fleksibilitas yang lebih, tapi aku'm tidak yakin itu's layak, terutama jika anda menggunakan kode pihak ketiga yang tidak't menggunakan kelas anda.Python wiki merupakan halaman untuk profil sumber daya: http://wiki.python.org/moin/PythonSpeed/PerformanceTips#Profiling_Code
seperti python docs: http://docs.python.org/library/profile.html
seperti yang ditunjukkan oleh Chris Lawlor cProfile adalah alat yang hebat dan dapat dengan mudah digunakan untuk mencetak ke layar:
atau untuk file:
PS> Jika anda menggunakan Ubuntu, pastikan untuk menginstal python-profil
Jika anda output ke file anda bisa mendapatkan bagus visualisasi menggunakan alat-alat berikut
PyCallGraph : alat untuk membuat panggilan grafik gambar
menginstal:
run:
lihat:
Anda dapat menggunakan apa pun yang anda suka untuk melihat file png, saya menggunakan gimp
Sayangnya saya sering mendapatkan
dot: grafik yang terlalu besar untuk kairo-penyaji bitmap. Scaling dengan 0.257079 untuk fit
yang membuat saya gambar unusably kecil. Jadi saya biasanya membuat file svg:
PS> pastikan untuk menginstal graphviz (yang menyediakan dot program):
Alternatif Grafik menggunakan gprof2dot via @maxy / @quodlibetor :
@Maxy's komentar pada jawaban membantu saya keluar cukup bahwa saya pikir itu layak jawabannya sendiri: saya sudah punya cProfile yang dihasilkan .pstats file dan saya didn't ingin kembali menjalankan hal-hal dengan pycallgraph, jadi saya menggunakan gprof2dot, dan punya cukup svg:
dan BLAM!
Menggunakan dot (hal yang sama bahwa pycallgraph menggunakan) sehingga output yang terlihat mirip. Saya mendapatkan kesan bahwa gprof2dot kehilangan informasi yang kurang meskipun:
Aku berlari ke sebuah alat yang berguna yang disebut SnakeViz ketika meneliti topik ini. SnakeViz adalah web-based profiling alat visualisasi. Hal ini sangat mudah untuk menginstal dan menggunakan. Cara yang biasa saya gunakan adalah untuk menghasilkan stat file
%prun
dan kemudian melakukan analisis di SnakeViz.Utama yaitu teknik yang digunakan adalah Sunburst grafik seperti yang ditampilkan di bawah ini, di mana hirarki fungsi panggilan diatur sebagai lapisan busur dan waktu info dikodekan dalam sudut lebar.
Hal terbaik adalah anda dapat berinteraksi dengan grafik. Misalnya, untuk zoom in one dapat klik pada busur dan busur dan keturunannya akan membesar seperti baru sunburst untuk menampilkan rincian lebih lanjut.
Saya berpikir bahwa
cProfile
lebih besar untuk profiling, sementarakcachegrind
sangat bagus untuk memvisualisasikan hasil. Thepyprof2calltree
di antara menangani konversi file.Untuk menginstal alat-alat yang diperlukan (pada Ubuntu, setidaknya):
Hasilnya:
Juga layak disebutkan adalah GUI cProfile dump viewer RunSnakeRun. Hal ini memungkinkan anda untuk memilah dan memilih, sehingga pembesaran pada bagian yang relevan dari program ini. Ukuran dari persegi panjang pada gambar tersebut adalah berbanding lurus dengan waktu yang dibutuhkan. Jika anda mengarahkan mouse di atas persegi panjang ini menyoroti bahwa panggilan di meja dan di mana-mana di peta. Ketika anda double-klik pada persegi panjang itu zoom in pada bagian itu. Ini akan menunjukkan kepada anda yang menyebut bahwa sebagian dan apa yang porsi panggilan.
Deskriptif informasi ini sangat membantu. Hal itu menunjukkan kode untuk yang sedikit yang dapat membantu ketika anda berurusan dengan built-in perpustakaan panggilan. Ini memberitahu anda apa file dan apa line untuk menemukan kode.
Juga ingin menunjukkan bahwa OP kata 'profil' tapi tampaknya ia berarti 'waktu'. Perlu diingat program akan berjalan lebih lambat ketika diprofilkan.
Sederhana dan cepat cara untuk menemukan di mana sepanjang waktu pergi.
Menarik pie chart di browser. Potongan terbesar adalah masalah fungsi. Sangat sederhana.
Bagus profiling modul line_profiler (disebut menggunakan script kernprof.py). Hal ini dapat diunduh disini.
Pemahaman saya adalah bahwa cProfile hanya memberikan informasi tentang jumlah waktu yang dihabiskan di masing-masing fungsi. Jadi individu baris kode tidak memiliki batas waktu. Ini adalah sebuah masalah pada komputasi ilmiah karena sering satu baris tunggal dapat mengambil banyak waktu. Juga, seperti yang saya ingat, cProfile didn't menangkap waktu saya belanja di katakan numpy.dot.
pprofile
line_profiler
(sudah disajikan di sini) juga terinspirasipprofile
, yang digambarkan sebagai:Ini memberikan garis-perincian sebagai
line_profiler
, adalah Python murni, dapat digunakan sebagai standalone perintah atau modul, dan bahkan dapat menghasilkan callgrind-format file yang dapat dengan mudah dianalisis dengan[k|q]cachegrind
.vprof
Ada juga vprof, paket Python digambarkan sebagai:
Saya baru-baru ini dibuat tuna untuk memvisualisasikan Python runtime dan profil impor; ini dapat membantu di sini.
Install dengan
pip3 menginstal tuna
Membuat runtime profilpython -mcProfile -o program.prof yourfile.py
atau mengimpor profil (Python 3.7+ diperlukan)python -X importprofile yourfile.py 2> impor.log
Kemudian hanya menjalankan tuna pada filetuna program.prof
Ada's banyak jawaban yang besar tetapi mereka juga menggunakan command line atau beberapa program eksternal untuk profiling dan/atau pemilahan hasil.
Aku benar-benar merindukan beberapa cara yang bisa saya gunakan dalam IDE (eclipse-PyDev) tanpa menyentuh baris perintah atau menginstal apapun. Jadi di sini adalah.
Profil tanpa baris perintah
Lihat docs atau jawaban lainnya untuk info lebih lanjut.
Berikut Joe Shaw's jawaban tentang multi-threaded kode tidak bekerja seperti yang diharapkan, saya pikir bahwa
runcall
metode dalam cProfile hanya melakukanself.aktifkan()
dandiri.menonaktifkan()
panggilan sekitar diprofilkan fungsi panggilan, sehingga anda hanya dapat melakukan itu sendiri dan memiliki apapun kode yang anda inginkan di antara dengan gangguan minimal dengan kode yang ada.Di Virtaal's sumber di sana's sangat berguna kelas dan dekorator yang dapat membuat profiling (bahkan untuk menemukan metode/fungsi) sangat mudah. Output yang kemudian dapat dilihat dengan sangat nyaman di KCacheGrind.
cProfile lebih besar untuk cepat profiling tetapi sebagian besar waktu itu adalah akhir bagi saya dengan kesalahan. Fungsi runctx memecahkan masalah ini dengan menginisialisasi dengan benar lingkungan dan variabel, berharap hal ini dapat berguna bagi seseorang:
Cara saya adalah dengan menggunakan yappi (https://code.google.com/p/yappi/). It's sangat berguna dikombinasikan dengan RPC server mana (bahkan hanya untuk debugging) anda mendaftar metode untuk memulai, berhenti dan cetak profiling informasi, misalnya dalam cara ini:
Kemudian ketika program anda bekerja, anda dapat mulai profiler setiap saat dengan memanggil
startProfiler
RPC metode dan dump profiling informasi ke file log dengan memanggilprintProfiler
(atau memodifikasi rpc metode untuk kembali ke pemanggil) dan mendapatkan output seperti:Hal itu mungkin tidak akan sangat berguna untuk jangka pendek script tapi membantu untuk mengoptimalkan server-jenis proses terutama mengingat
printProfiler
metode dapat disebut beberapa kali dari waktu ke waktu untuk profil dan bandingkan misalnya program yang berbeda skenario penggunaan.Jika anda ingin membuat kumulatif profiler, artinya untuk menjalankan fungsi beberapa kali berturut-turut dan menonton jumlah hasil.
anda dapat menggunakan ini
cumulative_profiler
dekorator:it's python >= 3.6 tertentu, tetapi anda dapat menghapus
nonlokal
untuk bekerja pada versi yang lebih tua.Contoh
profil fungsi
baz
baz
berlari 5 kali dan dicetak ini:menentukan jumlah kali
Untuk menambahkan pada https://stackoverflow.com/a/582337/1070617,
Saya menulis ini modul yang memungkinkan anda untuk menggunakan cProfile dan melihat output dengan mudah. Lebih lanjut di sini: https://github.com/ymichael/cprofilev
Juga melihat: http://ymichael.com/2014/03/08/profiling-python-with-cprofile.html tentang cara untuk membuat rasa yang dikumpulkan statistik.
Sebuah alat baru untuk menangani profil di Python adalah PyVmMonitor: http://www.pyvmmonitor.com/
Ini memiliki beberapa fitur unik seperti
Catatan:'s komersial, tetapi gratis untuk open source.