Anhängen, schlechte Leistung zu schneiden. warum?

8

Ich erstelle gerade ein Spiel mit GoLang. Ich vermesse den FPS. Ich bemerke einen Verlust von 7 fps mit einer for-Schleife, die wie folgt an ein Segment angehängt wird:

%Vor%

Ich mache das für jedes Sprite, für jeden Zug. Die Frage ist, warum bekomme ich einen so großen Performance-Hit, wenn ich nur für die Zeiten loope und das gleiche an diese Slices anfüge? Gibt es einen effizienteren Weg, dies zu tun? Es ist nicht so, als würde ich üppige Datenmengen hinzufügen. Jede Scheibe enthält ungefähr 16 Elemente wie oben gezeigt (4 x 4).

Wenn ich einfach alle 16 Elemente in ein []float32{1..16} setze, wird fps um etwa 4 verbessert.

Update: Ich habe jeden Anhang getestet und es scheint, dass jeder 1 fps ausführen muss. Das scheint eine Menge zu sein, wenn man bedenkt, dass diese Daten ziemlich statisch sind. Ich brauche nur 4 Iterationen ...

Update: Hinzugefügt github Repo Ссылка

    
efel 28.08.2015, 05:54
quelle

2 Antworten

6

Das eingebaute append() muss ein neues Backing-Array erstellen, wenn die Kapazität des Ziel-Slices kleiner ist als was die Länge der Scheibe nach dem Append wäre. Dies erfordert auch, dass die aktuellen Elemente vom Ziel in das neu zugewiesene Array kopiert werden, so dass viel Overhead entsteht.

Slices, an die Sie anhängen, sind wahrscheinlich leere Slices, da Sie ein Schnittliteral verwendet haben, um Ihren Opengl.OpenGLVertexInfo -Wert zu erstellen. Obwohl append() für die Zukunft denkt und ein größeres Array zuweist, als benötigt wird, um die angegebenen Elemente anzufügen, sind in Ihrem Fall mehrere Neuzuweisungen erforderlich, um die 4 Iterationen abzuschließen.

Sie können Neuzuweisungen vermeiden, wenn Sie vertexInfo wie folgt erstellen und initialisieren:

%Vor%

Beachten Sie auch, dass dieses Strukturliteral dafür sorgt, dass Arrays hinter den Slices nicht neu zugewiesen werden müssen. Aber wenn Sie an anderen Stellen Ihres Codes (die wir nicht sehen) weitere Elemente an diese Segmente anhängen, können sie Neuzuweisungen verursachen. Wenn dies der Fall ist, sollten Sie Schichten mit größerer Kapazität erstellen, die "zukünftige" Allokationen abdecken (z. B. make([]float64, 16, 32) ).

    
icza 28.08.2015, 06:28
quelle
4

Ein leeres Stück ist leer. Um anzuhängen, muss es Speicher reservieren. Und dann machst du mehr Attends, die noch mehr Speicher zuweisen müssen.

Um es zu beschleunigen, verwenden Sie ein Array fester Größe oder verwenden Sie make , um ein Segment mit der korrekten Länge zu erstellen, oder initialisieren Sie das Segment mit den Elementen, wenn Sie es deklarieren.

    
Zan Lynx 28.08.2015 06:08
quelle

Tags und Links