Saya baru-baru ini menjadi tertarik pada algoritma dan mulai mengeksplorasi mereka dengan menulis implementasi yang naif dan kemudian mengoptimalkannya dengan berbagai cara.
Saya sudah terbiasa dengan modul Python standar untuk profil runtime (untuk sebagian besar hal saya sudah menemukan fungsi sihir timeit di IPython sudah mencukupi), tapi saya juga tertarik dengan penggunaan memori sehingga saya dapat menjelajahi pengorbanan tersebut juga ( misalnya biaya caching tabel dari nilai yang sebelumnya dihitung versus mengkomputasi ulang sesuai kebutuhan). Apakah ada modul yang akan membuat profil penggunaan memori dari fungsi yang diberikan untuk saya?
Jawaban:
Yang ini sudah dijawab di sini: Python memory profiler
Pada dasarnya Anda melakukan hal seperti itu (dikutip dari Guppy-PE ):
sumber
Python 3.4 termasuk modul baru:
tracemalloc
. Ini memberikan statistik terperinci tentang kode mana yang mengalokasikan sebagian besar memori. Berikut adalah contoh yang menampilkan tiga baris teratas mengalokasikan memori.Dan inilah hasilnya:
Kapan kebocoran memori bukan kebocoran?
Contoh itu bagus ketika memori masih ditahan di akhir perhitungan, tetapi kadang-kadang Anda memiliki kode yang mengalokasikan banyak memori dan kemudian melepaskan semuanya. Secara teknis ini bukan kebocoran memori, tetapi menggunakan lebih banyak memori dari yang Anda kira seharusnya. Bagaimana Anda bisa melacak penggunaan memori ketika semuanya dilepaskan? Jika ini kode Anda, Anda mungkin dapat menambahkan beberapa kode debug untuk mengambil snapshot saat sedang berjalan. Jika tidak, Anda dapat memulai utas latar belakang untuk memantau penggunaan memori saat utas utama berjalan.
Inilah contoh sebelumnya di mana kode semuanya telah dipindahkan ke
count_prefixes()
fungsi. Ketika fungsi itu kembali, semua memori dilepaskan. Saya juga menambahkan beberapasleep()
panggilan untuk mensimulasikan perhitungan yang sudah berjalan lama.Ketika saya menjalankan versi itu, penggunaan memori telah dari 6MB ke 4KB, karena fungsi ini melepaskan semua memorinya ketika selesai.
Sekarang inilah versi yang terinspirasi oleh jawaban lain yang memulai utas kedua untuk memantau penggunaan memori.
The
resource
Modul memungkinkan Anda memeriksa penggunaan memori saat ini, dan menyimpan snapshot dari penggunaan memori puncak. Antrian memungkinkan utas utama memberitahu utas monitor memori kapan harus mencetak laporannya dan dimatikan. Saat dijalankan, ini menunjukkan memori yang digunakan olehlist()
panggilan:Jika Anda menggunakan Linux, Anda mungkin menemukan
/proc/self/statm
lebih berguna daripadaresource
modul.sumber
long_running()
di dalamcount_prefixes()
fungsi, nilai RSS maks tidak akan dicetak sampailong_running()
kembali. Atau saya salah?memory_monitor()
sedang berjalan di utas terpisah daricount_prefixes()
, jadi satu-satunya cara yang satu dapat mempengaruhi yang lain adalah GIL dan antrian pesan yang saya sampaikanmemory_monitor()
. Saya menduga bahwa ketikacount_prefixes()
panggilansleep()
, itu mendorong konteks utas untuk beralih. Jika Andalong_running()
tidak terlalu lama, maka konteks utas mungkin tidak beralih sampai Anda menekansleep()
panggilan kembalicount_prefixes()
. Jika itu tidak masuk akal, posting pertanyaan baru dan tautkan ke sini dari sini.Jika Anda hanya ingin melihat penggunaan memori suatu objek, ( jawab pertanyaan lain )
sumber
asizeof
asizeof
dapat berkontribusi untuk RSS, ya. Saya tidak yakin apa lagi yang Anda maksud dengan "terkait".tracemalloc
solusi di bawah ini lebih cepatPenyingkapan:
Tapi bagus karena kesederhanaannya:
Cukup masukkan di
using("Label")
mana Anda ingin melihat apa yang terjadi. Sebagai contohsumber
usage[2]
Anda melihatru_maxrss
, yang hanya merupakan bagian dari proses yang merupakan penduduk . Ini tidak akan banyak membantu jika proses telah ditukar ke disk, bahkan sebagian.resource
adalah modul khusus Unix yang tidak berfungsi di Windows.ru_maxrss
(yaitu,usage[2]
) adalah kB, bukan halaman sehingga tidak perlu untuk mengalikan angka itu denganresource.getpagesize()
.Karena jawaban yang diterima dan juga jawaban tertinggi berikutnya memiliki, menurut pendapat saya, beberapa masalah, saya ingin menawarkan satu jawaban lagi yang didasarkan erat pada jawaban Ihor B. dengan beberapa modifikasi kecil tapi penting.
Solusi ini memungkinkan Anda untuk menjalankan profil pada baik dengan membungkus panggilan fungsi dengan
profile
fungsi dan menyebutnya, atau dengan menghias fungsi / metode dengan@profile
dekorator.Teknik pertama berguna ketika Anda ingin profil beberapa kode pihak ketiga tanpa mengacaukan sumbernya, sedangkan teknik kedua agak "bersih" dan bekerja lebih baik ketika Anda tidak keberatan memodifikasi sumber fungsi / metode yang Anda gunakan. ingin profil.
Saya juga memodifikasi output, sehingga Anda mendapatkan RSS, VMS, dan memori bersama. Saya tidak terlalu peduli dengan nilai "sebelum" dan "setelah", tetapi hanya delta, jadi saya menghapusnya (jika Anda membandingkan dengan jawaban Ihor B.).
Kode profil
Contoh penggunaan, dengan asumsi kode di atas disimpan sebagai
profile.py
:Ini akan menghasilkan output yang mirip dengan di bawah ini:
Beberapa catatan akhir yang penting:
profile(my_function, arg)
untuk profilmy_function(arg)
sumber
Di bawah ini adalah dekorator fungsi sederhana yang memungkinkan untuk melacak berapa banyak memori proses yang dikonsumsi sebelum panggilan fungsi, setelah panggilan fungsi, dan apa bedanya:
Ini blog saya yang menjelaskan semua detail. ( tautan yang diarsipkan )
sumber
process.memory_info().rss
tidakprocess.get_memory_info().rss
, setidaknya di ubuntu dan python 3.6. terkait stackoverflow.com/questions/41012058/psutil-error-on-macosmungkin ini membantu:
< lihat tambahan >
sumber
sumber