Heim >Backend-Entwicklung >Python-Tutorial >Leistungsfalle: allgemeine Bibliotheken und Hilfsobjekte

Leistungsfalle: allgemeine Bibliotheken und Hilfsobjekte

Susan Sarandon
Susan SarandonOriginal
2024-10-10 08:12:02829Durchsuche

Bequemlichkeit und Leistung korrelieren typischerweise umgekehrt. Wenn der Code einfach zu verwenden ist, ist er weniger optimiert. Wenn es optimiert ist, ist es weniger praktisch. Effizienter Code muss näher an die wesentlichen Details dessen herangehen, was tatsächlich läuft und wie.

Ich bin bei unserer laufenden Arbeit zur Durchführung und Optimierung der DeepCell-Zellsegmentierung für die Krebsforschung auf ein Beispiel gestoßen. Das DeepCell-KI-Modell sagt voraus, welche Pixel sich am wahrscheinlichsten in einer Zelle befinden. Von dort aus „fluten wir“ die wahrscheinlichsten Pixel, bis wir den Zellrand erreichen (unterhalb eines bestimmten Schwellenwerts).

Ein Teil dieses Prozesses besteht darin, kleine Lücken innerhalb der vorhergesagten Zellen zu glätten, was aus verschiedenen Gründen passieren kann, aber biologisch nicht möglich ist. (Denken Sie an Donut-Löcher, nicht an die poröse Membran einer Zelle.)

Der Lochfüllalgorithmus funktioniert folgendermaßen:

  • Objekte identifizieren (zusammenhängende Pixel mit einer bestimmten Zellenbezeichnung und derselben numerischen ID).
  • Berechnen Sie die „Eulerzahl“ dieser Zellen, ein Maß für die Oberfläche der Form.
  • Wenn die Euler-Zahl kleiner als 1 ist (d. h. die Oberfläche weist Lücken auf), glätten Sie die Löcher.

Hier ist ein Beispiel für Euler-Zahlen aus dem Wikipedia-Artikel; Ein Kreis (nur der Linienteil) hat eine Euler-Charakteristik von Null, während eine Scheibe (der „ausgefüllte“ Kreis) den Wert 1 hat.

Performance trap: general libraries & helper objects

Wir sind jedoch nicht hier, um über die Definition oder Berechnung von Euler-Zahlen zu sprechen. Wir werden darüber sprechen, dass der einfache Weg der Bibliothek zur Berechnung von Euler-Zahlen ziemlich ineffizient ist.

Das Wichtigste zuerst. Das Problem ist uns aufgefallen, als wir dieses Profil mit Speedscope betrachtet haben:

Performance trap: general libraries & helper objects

Es zeigt, dass ca. 32 ms (~15 %) in Regionprops verbracht wurden. Diese Ansicht ist linkslastig. Wenn wir zur Zeitleistenansicht gehen und hineinzoomen, erhalten wir Folgendes:

Performance trap: general libraries & helper objects

(Beachten Sie, dass wir dies zweimal tun, daher ~16 ms hier und ~16 ms anderswo, nicht gezeigt.)

Das ist sofort verdächtig: Der „interessante“ Teil beim Finden der Objekte mit find_objects ist der erste Splitter, 0,5 ms. Es gibt eine Liste von Tupeln zurück, keinen Generator. Wenn es also fertig ist, ist es fertig. Was ist mit all den anderen Sachen los? Wir erstellen RegionProperties-Objekte. Lassen Sie uns einen davon vergrößern.

Performance trap: general libraries & helper objects

Die winzigen Splitter (auf die wir nicht näher eingehen) sind benutzerdefinierte __setattr__-Aufrufe: Die RegionProperties-Objekte unterstützen Aliasing. Wenn Sie beispielsweise das Attribut ConvexArea festlegen, wird auf ein Standardattribut „area_convex“ umgeleitet. Auch wenn wir davon keinen Gebrauch machen, durchlaufen wir dennoch den Attributkonverter.

Außerdem: Wir nutzen die meisten der in den Regionseigenschaften berechneten Eigenschaften gar nicht. Uns interessiert nur die Euler-Zahl:

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

Dabei wird wiederum nur der grundlegendste Aspekt der Regionseigenschaften verwendet: die von find_objects erkannten Bildregionen (Teile des Originalbilds).

Also haben wir den Code in den Code „fill_holes“ geändert, um einfach die Allzweckfunktion „regionprops“ zu umgehen. Stattdessen rufen wir find_objects auf und übergeben die resultierenden Bildunterregionen an die Funktion euler_number (nicht die Methode für ein RegionProperties-Objekt).

Hier ist die Pull-Anfrage: deepcell-imaging#358 Regionprops-Konstruktion überspringen

Durch das Überspringen des Zwischenobjekts haben wir eine deutliche Leistungsverbesserung für die Operation „fill_holes“ erzielt:

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

Für das größere Bild machen 4 Sekunden etwa 3 % der Gesamtlaufzeit aus – nicht der größte Teil davon, aber auch nicht allzu schäbig.

Das obige ist der detaillierte Inhalt vonLeistungsfalle: allgemeine Bibliotheken und Hilfsobjekte. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn