So optimieren Sie das Programm golang, das die meiste Zeit in runtime.osyield und runtime.usleep verbringt

8

Ich habe daran gearbeitet, Code zu optimieren, der soziale Graphendaten analysiert (mit Hilfe von Ссылка ). und ich habe eine Menge langsamen Code erfolgreich überarbeitet.

Alle Daten werden zuerst von db in den Speicher geladen, und die Datenanalyse von dort erscheint CPU-gebunden (max Speicherverbrauch & lt; 10 MB, CPU1 @ 100%)

Aber jetzt scheint die meiste Zeit meines Programms in runtime.osyield und runtime.usleep zu liegen. Wie kann man das verhindern?

Ich habe GOMAXPROCS = 1 gesetzt und der Code spawnt keine goroutines (außer was die Golang-Bibliotheken nennen).

Dies ist meine Top10-Ausgabe von pprof

%Vor%

Die Funktionen _ / C_ / code / sc_proto / * sind mein Code.

Und die Ausgabe aus dem Web:

(besser, SVG-Version des Graphen hier: Ссылка )

    
Aaron 02.02.2016, 13:41
quelle

1 Antwort

5

Ich habe die Antwort selbst gefunden, also poste ich das hier für jeden, der ein ähnliches Problem hat. Ein besonderer Dank geht an @JimB, der mir den richtigen Weg geschickt hat.

Wie aus der Grafik ersichtlich, sind die Pfade, die zu osyield und usleep führen, Garbage-Collection-Routinen. Dieses Programm verwendete eine verkettete Liste, die viele Zeiger erzeugte, was eine Menge Arbeit für den GC erzeugte, der gelegentlich die Ausführung meines Codes blockierte, während er mein Durcheinander bereinigte.

Letztendlich kam die Lösung für dieses Problem von Ссылка (was eine tolle Quelle war). Ich folgte den Anweisungen zum Speicherprofiler dort; und die Empfehlung, Sammlungen von Zeigern durch Scheiben zu ersetzen, hat meine Garbage Collection-Probleme geklärt, und mein Code ist jetzt viel schneller !

    
Aaron 02.02.2016, 17:57
quelle

Tags und Links