<canvas id="c" width="800" height="300"></canvas>
$c = document.getElementById('c');
$ctx = $c.getContext('2d');
$ctx.clearRect(0, 0, 800, 300);
$px = $ctx.createImageData(1, 1);
$pxls = [];
for (var i=0; i<1000000; ++i) $pxls.push({
x: Math.random() * 800 << 0,
y: Math.random() * 300 << 0,
r: Math.random() * 255 << 0,
g: Math.random() * 255 << 0,
b: Math.random() * 255 << 0,
a: Math.random() * 128 << 0 + 128
});
$i = 0;
for (var i=500;i--;){
var px = $pxls[$i++ % 1000000];
$ctx.fillStyle = 'rgba(' + px.r + ',' + px.g + ',' + px.b + ',' + (px.a / 255) + ')';
$ctx.fillRect(px.x, px.y, 1, 1);
}
for (var i=500;i--;){
var px = $pxls[$i++ % 1000000];
$ctx.fillStyle = 'rgba(' + [px.r,px.g,px.b,px.a/255].join() + ')';
$ctx.fillRect(px.x, px.y, 1, 1);
}
for (var i=500;i--;){
var px=$pxls[$i++ % 1000000], d=$px.data;
d[0] = px.r;
d[1] = px.g;
d[2] = px.b;
d[3] = px.a;
$ctx.putImageData($px, px.x, px.y);
}
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
fillRect/concat | |
fillRect/join | |
1×1 Image Data |
Test name | Executions per second |
---|---|
fillRect/concat | 356.3 Ops/sec |
fillRect/join | 340.5 Ops/sec |
1×1 Image Data | 3164.2 Ops/sec |
Let's break down the benchmark and its various components.
Benchmark Overview
The benchmark is designed to test the performance of drawing 1x1 pixels on a canvas element using different approaches. The benchmark creates an array of 1 million pixel data objects, each representing a single pixel with red, green, blue, and alpha channels. It then uses these pixel data objects to draw 1x1 pixels on a canvas element.
Script Preparation Code
The script preparation code initializes the following variables:
$c
: a reference to the canvas element$ctx
: a 2D drawing context for the canvas element$pxls
: an array of 1 million pixel data objectsThe code also clears the canvas element and creates a new image data object $px
.
Html Preparation Code
The HTML preparation code sets up the basic structure for the benchmark, including:
Individual Test Cases
There are three test cases, each defining a different approach to drawing 1x1 pixels on the canvas element.
fillRect/concat
This test case uses string concatenation to build the color string for each pixel:
$ctx.fillStyle = 'rgba(' + px.r + ',' + px.g + ',' + px.b + ',' + (px.a / 255) + ')';
The pros of this approach are that it's concise and easy to read. However, it may lead to slower performance due to the overhead of string concatenation.
fillRect/join
This test case uses an array join method to build the color string for each pixel:
$ctx.fillStyle = 'rgba(' + [px.r,px.g,px.b,px.a/255].join() + ')';
The pros of this approach are that it's potentially faster than concatenation because it avoids creating temporary strings. However, it may be less readable than the other approach.
1×1 Image Data
This test case uses the putImageData
method to draw 1x1 pixels on the canvas element:
$ctx.putImageData($px, px.x, px.y);
The pros of this approach are that it's potentially faster than other approaches because it avoids manual drawing. However, it may be less efficient due to the overhead of creating an image data object.
Library: 2D Drawing Context
The $ctx
variable is a 2D drawing context for the canvas element. It provides methods for drawing shapes, lines, and text on the canvas.
Special JS Feature: None
There are no special JavaScript features or syntax used in this benchmark that would require additional explanation.
Other Alternatives
If you were to rewrite this benchmark using alternative approaches, here are a few options: