2015-03-05 3 views
9

Also, ich habe gehört, dass Sie angeblich alle phantastischen Echtzeit-Spiele mit JS in diesen Tagen tun können. Und ich bin kein Anfänger, also sollte ich es versuchen. Schrieb einige Mikro- (unvollständige) Physik-Engine mit einer Kollisionserkennung, alle süß. Etwas verzögert, aber erwartete GC Interrupts. Also habe ich versucht, jede Zuweisung zu minimieren, bis ich nichts mehr sehen konnte, das Speicher in Spielschleife zuweisen sollte. Keine Zuweisungen => keine Aufräumarbeiten. Aber hier ist, was ich bekomme: enter image description hereWas isst meine Erinnerung? (Die SAW, JS mem usage edition)

Nun, das ist überhaupt nicht sauber. Also habe ich versucht, meine Sachen aus der Spieleschleife auf verschiedene Arten zu entfernen. Immer noch SAH. Also nein, ich präsentiere Ihnen den kompletten Code, der das erzeugt:

<html><body><script> 
    function draw() { console.log(1); } 
    ;(function() { 
     function main(tFrame) { draw(); window.requestAnimationFrame(main); } 
     main(); 
    })(); 
</script></body></html> 

Erstaunlich? Nun, das verwendet requestAnimationFrame, wie es scheint, das sollte für eine reibungslose Leistung verwendet werden. Zuerst habe ich versucht, Intervall so einzustellen:

<html><body><script> 
    function draw() { console.log(1); } 
    window.setInterval(draw, 0); 
</script></body></html> 

Genau das gleiche!

Das scheint völlig inakzeptabel, aber ich habe keine Ideen, wie man diese SAW stoppen kann. Ich habe viel über das Debuggen von Speicher und so weiter nachgedacht, das war während ich dieses Problem in meinen Zeichen- und Aktualisierungsfunktionen hatte. Aber diese zu Schnipsel, haben im Grunde nichts, und doch erzeugen sie diese Erinnerungspattern. Vielleicht ist es mein Browser? Oder ist es unausweichlich und JS ist für irgendetwas in Echtzeit unbrauchbar? Ich würde gerne glauben, dass jemand im Internet etwas weiß, was ich nicht tue, da viele Leute Wunder mit JS versprechen. Was mache ich in diesen Schnipsel falsch?

BEARBEITEN: Übrigens ändert das Entfernen des Konsolenprotokolls nichts, falls jemand denkt, dass das Problem ist.

+0

Alle Browser-Plugins laufen im Hintergrund? –

+0

Auch wenn jemand dies nicht reproduzieren kann, wäre es interessant, OS und Browser Version zu hören. Ich bin im Linux-Test mit Chromium 35.0.1916.153. – morphles

+0

@sixfingeredman nein, nur ein paar offene Tabs auf leer (gut etwas wurde geöffnet, aber ich "backed"). Nicht, dass das irgendeinen Effekt haben sollte, da chrome Process Isolation hat, und ich hoffe, dass es erkennen kann, ob das Plug-in oder die Seite CPU und insbesondere mem verwendet. – morphles

Antwort

5

Lassen Sie uns diesen Code ein bisschen analysieren:

  • Sie erstellen 3 Funktionen beim Start
  • Sie erstellen 1 integer pro Zeichenaufruf (60+ mal pro Sekunde)
  • Sie melden einmal pro ziehen Anruf (die übrigens super langsam ist)

Hier ist die Leistung ganzen Zahlen schaffen vs nichts gegen die Protokollierung in JavaScript zu tun:

Creating Integers versus logging them

http://jsperf.com/creating-integers

Sie sind jedoch recht. Nachdem ich eine about:blank Seite besucht und den Code ein wenig optimiert habe, habe ich einige interessante Daten bekommen.

Code:

function draw() { 1; } 

function main(tFrame) { 
    draw(); 
    window.requestAnimationFrame(main); 
} 

main(); 

Daten:

GC JS Saw

Dieser Graph zwischen 4,6MB und 5,2MB schwankt. Nicht wirklich eine große Sache. Ein halbes Megabyte Speicher ist wirklich schnell. Leider gibt es keine Möglichkeit, dies zu vermeiden.Ich habe folgendes versucht:

var j = 1; 

function draw() { j; } 

Und während es weniger Müll zu sammeln gab; GC lief immer noch. Auf der positiven Seite in beide diesem Beispiel und dem vorherigen unseren Code zu allen Zeiten bei 60fps läuft:

60fps... no logging

Moral der Geschichte: Protokollierung ist teuer. Es ist immer teuer; Javascript oder nicht.

+0

Logging war eigentlich da, um sicherzustellen, dass der Code Looping war, und ich habe ihn nicht entfernt, als ich eine Aufgabe gepostet habe. Mein Hauptproblem besteht darin, dass dies, wie du siehst, auch passiert, wenn es heißt, dass es auch dann passiert, wenn der Funktionskörper leer ist. Da es kein Problem ist, würde ich sagen, dass es so ist. In meinem realen Code mit Simulation ist sichtbar, dass einige Frames länger brauchen. Interessant ist auch, dass leere Codesägezähne etwa 30 Sekunden dauern, aber bei der Simulation sind die Zähne wesentlich kürzer, vielleicht sogar eine kleine Sekunde. – morphles

+0

@morples Ich weiß nicht genau, was Sie während Ihrer Schleife tun. JS ist single-threaded und benötigt mehr Aufmerksamkeit, um eine gute Leistung zu erzielen. Allgemeine Tipps: 1) Sie sollten eine Strategie entwickeln, um möglichst während der Render-Schleife nicht zu aktualisieren. Ich gehe oft mit Ereignissen außerhalb der Schleife um und lasse sie Daten optimieren. Auf diese Weise bleibt die Renderschleife ein schreibgeschützter Codepfad. 2) vereinfachen Sie Ihre Szene in irgendeiner Weise (culling/Detaillierungsgrad/rtrees), damit Sie nur bestimmte Teile des Bildschirms bearbeiten können. 3) Wenn Sie unbedingt mehr Pferdestärke benötigen, ziehen Sie Web-Arbeiter in Betracht. 4) typisierte Arrays. Benutzt du webgl? – Parris

+0

Ja, vielleicht werde ich versuchen, Updates in das Zeitlimit zu verschieben und die Zeichnung dem Animframe zu überlassen. 2, für jetzt ist schiene sehr einfach, sogar ein paar Bälle, die von Linien springen, sehen genauso aus wie 300 Bälle (was komisch ist, und das macht mich GC mehr als alles andere verdächtig). Im Moment bezweifle ich, dass typisierte Arrays mir viel geben würden (wieder 300 vs 3 Bälle, lag scheint gleich). Ich benutze Webgl nicht und möchte es nicht wirklich benutzen. – morphles