2016-07-04 3 views
1

Warum ist es, dass diese:Warum sind mehrere Aufrufe von fillRect() langsamer als ein Aufruf von fillRect()?

var rows = 80 
var cols = 120 
var tw = 5 

for(var i = 0; i < rows; i++){ 
    for(var j = 0; j < cols; j++){ 
     context.fillRect(j*tw, i*tw, tw, tw) 
    } 
} 

läuft so viel langsamer als das:

context.fillRect(0, 0, canvas.width, canvas.height) 

, wenn sie in der gleichen Anzahl von Pixeln zu füllen? Ich dachte naiv, dass fillRec() nur eine Reihe von Pixeln ausfüllen würde, aber offensichtlich macht es etwas anderes. Was macht es sonst noch?

+1

Für jeden Aufruf gibt es eine Menge von Eingangsvariablen Typ-Konvertierung, Validierung Parametern sein wird, ruft in dem, was Grafik-Engine die sie verwenden, etc, etc, dass bald die tatsächliche Pixel Zeichnung aufwiegen. Des Weiteren kann die Pixel Zeichnung Optimierungen haben für Zeichnung 4 oder 8 Pixel in einer einzigen Anweisung, die Sie nicht in Anspruch nehmen können, wenn zu einem Zeitpunkt, um ein Pixel zu tun. –

Antwort

1

In Scanzeilenalgorithmen gibt es eine Menge Code, der das Rendern von Pixeln optimiert. Die aktuelle Transformation wird angewendet, dann das Clipping und dann die Kantensortierung. Dies muss geschehen, bevor die Pixel geschrieben werden. Sie sind am effizientesten, wenn die Anzahl der Pixel zunimmt.

Um die Geschwindigkeit zu verbessern und haben die GPU Pixel machen, machen die erste rect kopieren Sie dann, dass über die drawImage ruft wie folgt.

var rows = 80; 
var cols = 120; 
var tw = 5; 
ctx.fillRect(0, 0, tw, tw); 
for(var i = 0; i < rows; i++){ 
    for(var j = 0; j < cols; j++){ 
     if(i+j !== 0){ 
      ctx.drawImage(ctx.canvas,0,0,tw,tw,j*tw, i*tw, tw, tw); 
     } 
    } 
} 

Wird schneller sein als alle fillRect-Aufrufe.

Obwohl die Verbesserung vergleicht nicht auf einen einzigen Anruf machen, Bitmaps Zeichnung verwendet den Hardware-Pixel zu machen, während fillRect viel mehr angewiesen ist (ganz oder teil Ich bin nicht sicher von der verwendeten Methode) auf Software-Rendering

+0

Was macht das 'if (i + j === 0)'? –

+0

@NickFegley Stoppt den Code vom Zeichnen über das erste Rechteck .. Oh mein Schlechter sollte! == sein – Blindman67