Rumah >pembangunan bahagian belakang >Tutorial Python >Perangkap prestasi: perpustakaan umum & objek pembantu

Perangkap prestasi: perpustakaan umum & objek pembantu

Susan Sarandon
Susan Sarandonasal
2024-10-10 08:12:02829semak imbas

Kemudahan dan prestasi biasanya berkorelasi songsang. Jika kod itu mudah digunakan, ia kurang dioptimumkan. Jika ia dioptimumkan, ia kurang mudah. Kod yang cekap perlu mendekati butiran terperinci tentang perkara yang sebenarnya sedang dijalankan, bagaimana.

Saya menemui contoh dalam kerja berterusan kami untuk menjalankan & mengoptimumkan segmentasi selular DeepCell untuk penyelidikan kanser. Model DeepCell AI meramalkan piksel mana yang berkemungkinan besar berada dalam sel. Dari situ, kami "membanjiri" daripada piksel yang paling berkemungkinan, sehingga mencapai sempadan sel (di bawah beberapa ambang).

Sebahagian daripada proses ini melibatkan melicinkan celah kecil di dalam sel yang diramalkan, yang boleh berlaku atas pelbagai sebab tetapi tidak mungkin secara biologi. (Fikirkan lubang donat, bukan membran berliang sel.)

Algoritma pengisian lubang adalah seperti ini:

  • Kenal pasti objek (piksel bersebelahan dengan label sel tertentu dengan id angka yang sama).
  • Hitung "nombor Euler" sel ini, ukuran permukaan bentuk.
  • Jika Nombor Euler kurang daripada 1 (aka permukaannya mempunyai celah), ratakan lubang tersebut.

Berikut ialah contoh nombor Euler daripada artikel Wikipedia; bulatan (hanya bahagian garisan) mempunyai ciri Euler sifar manakala cakera (bulatan "diisi") mempunyai nilai 1.

Performance trap: general libraries & helper objects

Kami di sini bukan untuk bercakap tentang mentakrifkan atau mengira nombor Euler. Kita akan bercakap tentang cara laluan mudah perpustakaan untuk mengira nombor Euler agak tidak cekap.

Perkara pertama dahulu. Kami melihat masalah itu dengan melihat profil ini menggunakan Speedscope:

Performance trap: general libraries & helper objects

Ia menunjukkan ~32ms (~15%) dibelanjakan dalam regionprops. Paparan ini berat sebelah kiri, jika kita pergi ke paparan garis masa dan zum masuk, kita mendapat ini:

Performance trap: general libraries & helper objects

(Perhatikan bahawa kami melakukan ini dua kali, oleh itu ~16ms di sini dan ~16ms di tempat lain, tidak ditunjukkan.)

Ini segera disyaki: bahagian "menarik" untuk mencari objek dengan find_objects ialah sekerat pertama, 0.5ms. Ia mengembalikan senarai tupel, bukan penjana, jadi apabila ia selesai ia selesai. Jadi apa jadi dengan semua perkara lain? Kami sedang membina objek RegionProperties. Mari zum masuk pada salah satu daripadanya.

Performance trap: general libraries & helper objects

Sekerat kecil (yang kami tidak akan zum masuk) ialah panggilan __setattr__ tersuai: objek RegionProperties menyokong pengaliansi, contohnya jika anda menetapkan atribut ConvexArea ia mengubah hala ke area_convex atribut standard. Walaupun kami tidak menggunakannya, kami masih melalui penukar atribut.

Tambahan pula: kami tidak menggunakan kebanyakan sifat yang dikira dalam sifat wilayah. Kami hanya mementingkan nombor Euler:

props = regionprops(np.squeeze(label_img.astype('int')), cache=False)
for prop in props:
    if prop.euler_number < 1:

sebaliknya, ia hanya menggunakan aspek paling asas bagi sifat rantau: kawasan imej yang dikesan oleh find_objects (kepingan imej asal).

Jadi, kami menukar kod kepada kod fill_holes untuk memintas sahaja fungsi tujuan am regionprops. Sebaliknya, kami memanggil find_objects dan menghantar subkawasan imej yang terhasil kepada fungsi euler_number (bukan kaedah pada objek RegionProperties).

Berikut ialah permintaan tarik: deepcell-imaging#358 Langkau pembinaan regionprops

Dengan melangkau objek perantaraan, kami mendapat peningkatan prestasi yang baik untuk operasi fill_holes:

Image size Before After Speedup
260k pixels 48ms 40ms 8ms (17%)
140M pixels 15.6s 11.7s 3.9s (25%)

Untuk imej yang lebih besar, 4s ialah ~3% daripada keseluruhan masa jalan– bukan sebahagian besarnya, tetapi juga tidak terlalu lusuh.

Atas ialah kandungan terperinci Perangkap prestasi: perpustakaan umum & objek pembantu. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn