canvas pixel loop (v6)

Revision 6 of this benchmark created on


Description

Benchmark different methods for looping a simple filter through image pixels.

Preparation HTML

<script>
  var canvas = document.createElement('canvas');
  canvas.width = 1024;
  canvas.height = 1024;
  var ctx = canvas.getContext('2d');
  ctx.fillRect(0, 0, 1024, 1024);
  var id = ctx.getImageData(0, 0, 1024, 1024);
  var pixels = id.data;
  var length = pixels.length;
  var width = id.width;
  var height = id.height;
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
property accesses 2d
for (var y = 0; y < id.height; y++) {
  for (var x = 0; x < id.width; x++) {
    var off = (y * id.width + x) * 4;
    id.data[off] += 10;
    id.data[off + 1] += 20;
    id.data[off + 2] += 30;
    id.data[off + 3] += 40;
  }
}
ready
property accesses 1d
for (var i = 0; i < id.data.length; i += 4) {
  id.data[i] += 10;
  id.data[i + 1] += 20;
  id.data[i + 2] += 30;
  id.data[i + 3] += 40;
}
ready
local variables 2d
for (var y = 0; y < height; y++) {
  for (var x = 0; x < width; x++) {
    var off = (y * width + x) * 4;
    pixels[off] += 10;
    pixels[off + 1] += 20;
    pixels[off + 2] += 30;
    pixels[off + 3] += 40;
  }
}
ready
local variables 1d
for (var i = 0; i < length; i += 4) {
  pixels[i] += 10;
  pixels[i + 1] += 20;
  pixels[i + 2] += 30;
  pixels[i + 3] += 40;
}
ready
local variables 1d hack one
for (var i = -1; i < length;) {
  pixels[++i] += 10;
  pixels[++i] += 20;
  pixels[++i] += 30;
  pixels[++i] += 40;
}
ready
local variables 1d hack two
var i = -1;
while (i < length) {
  pixels[++i] += 10;
  pixels[++i] += 20;
  pixels[++i] += 30;
  pixels[++i] += 40;
}
ready
local variables 1d hack three
var i = length;
while (i >= 0) {
  pixels[--i] += 40;
  pixels[--i] += 30;
  pixels[--i] += 20;
  pixels[--i] += 10;
}
ready
local variables 2d cache-unfriendly
for (var x = 0; x < width; x++) {
  for (var y = 0; y < height; y++) {
    var off = (y * width + x) * 4;
    pixels[off] += 10;
    pixels[off + 1] += 20;
    pixels[off + 2] += 30;
    pixels[off + 3] += 40;
  }
}
ready
local variables 1d hack four
for (var i = 0; i < length;) {
  pixels[i++] += 10;
  pixels[i++] += 20;
  pixels[i++] += 30;
  pixels[i++] += 40;
}
ready
local variables 2d w/ bit-shifts
for (var y = 0; y < height; y++) {
  for (var x = 0; x < width; x++) {
    var off = (((y << 8) + x) << 2);
    pixels[off] += 10;
    pixels[off + 1] += 20;
    pixels[off + 2] += 30;
    pixels[off + 3] += 40;
  }
}
ready
multiple getImageData calls
for (var y = 0; y < height; y++) {
  for (var x = 0; x < width; x++) {
    var pixel = ctx.getImageData(x, y, 1, 1).data;
    pixel[0] += 10;
    pixel[1] += 20;
    pixel[2] += 30;
    pixel[3] += 40;
  }
}
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.