jsPerf.app is an online JavaScript performance benchmark test runner & jsperf.com mirror. It is a complete rewrite in homage to the once excellent jsperf.com now with hopefully a more modern & maintainable codebase.
jsperf.com URLs are mirrored at the same path, e.g:
https://jsperf.com/negative-modulo/2
Can be accessed at:
https://jsperf.app/negative-modulo/2
Tests two different methods of manipulating pixels using the canvas.
NOTE: Now takes endianness into account.
<canvas id="canvas" height="256" width="256"></canvas>
var canvas = document.getElementById('canvas');
var canvasWidth = canvas.width;
var canvasHeight = canvas.height;
var ctx = canvas.getContext('2d');
var imageData = ctx.getImageData(0, 0, canvasWidth, canvasHeight);
var data = imageData.data;
var buf = new ArrayBuffer(imageData.data.length);
var buf8 = new Uint8ClampedArray(buf);
var data32 = new Uint32Array(buf);
// Determine whether Uint32 is little- or big-endian.
data32[1] = 0x0a0b0c0d;
var isLittleEndian = true;
if (buf[4] === 0x0a && buf[5] === 0x0b && buf[6] === 0x0c &&
buf[7] === 0x0d) {
isLittleEndian = false;
}
!function(e){"object"==typeof exports?module.exports=e():"function"==typeof define&&define.amd?define(e):"undefined"!=typeof window?window.ImageBuffer=e():"undefined"!=typeof global?global.ImageBuffer=e():"undefined"!=typeof self&&(self.ImageBuffer=e())}(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){function isLittleEndian(){var a=new ArrayBuffer(4);var b=new Uint8Array(a);var c=new Uint32Array(a);b[0]=161;b[1]=178;b[2]=195;b[3]=212;if(c[0]==3569595041)return true;if(c[0]==2712847316)return false;else{return null}}function isUint8ClampedImageData(){if(typeof Uint8ClampedArray==="undefined")return false;var elem=document.createElement("canvas");var ctx=elem.getContext("2d");if(!ctx)return false;var image=ctx.createImageData(1,1);return image.data instanceof Uint8ClampedArray}var LITTLE_ENDIAN=isLittleEndian();var SUPPORTS_32BIT=typeof ArrayBuffer!=="undefined"&&typeof Uint8ClampedArray!=="undefined"&&typeof Int32Array!=="undefined"&&LITTLE_ENDIAN!==null&&isUint8ClampedImageData();var ImageBuffer=function(width,height){this.imageData=null;if(typeof width!=="number"){this.imageData=width;width=this.imageData.width;height=this.imageData.height}this.width=width;this.height=height;this.pixels=null;this.direct=false;this.uint8=null;if(this.imageData){this.direct=true;if(SUPPORTS_32BIT){this.uint8=this.imageData.data;this.pixels=new Int32Array(this.uint8.buffer)}else{this.pixels=this.uint8=this.imageData.data}}else{if(SUPPORTS_32BIT){this.uint8=new Uint8ClampedArray(width*height*ImageBuffer.NUM_COMPONENTS);this.pixels=new Int32Array(this.uint8.buffer)}else{this.pixels=this.uint8=new Array(width*height*ImageBuffer.NUM_COMPONENTS)}}};ImageBuffer.prototype.constructor=ImageBuffer;ImageBuffer.prototype.setPixelAt=function(x,y,r,g,b,a){var i=~~(x+y*this.width);this.setPixel(i,r,g,b,a)};ImageBuffer.prototype.getColorAt=function(x,y,out){var i=~~(x+y*this.width);return this.getPixel(i,out)};ImageBuffer.prototype.createImage=function(context){var canvas;if(!context){canvas=document.createElement("canvas");context=canvas.getContext("2d")}else{canvas=context.canvas}if(typeof canvas.toDataURL!=="function")throw new Error("Canvas.toDataURL is not supported");canvas.width=this.width;canvas.height=this.height;var imageData=this.imageData;if(!this.direct||!this.imageData){imageData=context.createImageData(this.width,this.height);this.apply(imageData)}context.clearRect(0,0,this.width,this.height);context.putImageData(imageData,0,0);var img=new Image;img.src=canvas.toDataURL.apply(canvas,Array.prototype.slice.call(arguments,1));imageData=null;context=null;canvas=null;return img};ImageBuffer.prototype.apply=function(imageData){if(this.imageData===imageData&&this.direct){return}if(SUPPORTS_32BIT){if(imageData instanceof ImageBuffer){imageData.pixels.set(this.pixels)}else{imageData.data.set(this.uint8)}}else{var data=imageData instanceof ImageBuffer?imageData.pixels:imageData.data;if(!data)throw new Error("imageData must be an ImageBuffer or Canvas ImageData object");var pixels=this.pixels;if(data.length!==pixels.length)throw new Error("the image data for apply() must have the same dimensions");for(var i=0;i<pixels.length;i++){data[i]=pixels[i]}}};ImageBuffer.NUM_COMPONENTS=4;ImageBuffer.SUPPORTS_32BIT=SUPPORTS_32BIT;ImageBuffer.LITTLE_ENDIAN=LITTLE_ENDIAN;if(SUPPORTS_32BIT){if(LITTLE_ENDIAN){ImageBuffer.prototype.setPixel=function(index,r,g,b,a){this.pixels[index]=a<<24|b<<16|g<<8|r}}else{ImageBuffer.prototype.setPixel=function(index,r,g,b,a){this.pixels[index]=r<<24|g<<16|b<<8|a}}}else{ImageBuffer.prototype.setPixel=function(index,r,g,b,a){var pixels=this.pixels;index*=4;pixels[index]=r;pixels[++index]=g;pixels[++index]=b;pixels[++index]=a}}ImageBuffer.prototype.getPixel=function(index,out){var pixels=this.uint8;index*=4;if(!out)out={r:0,g:0,b:0,a:0};out.r=pixels[index];out.g=pixels[++index];out.b=pixels[++index];out.a=pixels[++index];return out};if(LITTLE_ENDIAN){ImageBuffer.packPixel=function(r,g,b,a){return a<<24|b<<16|g<<8|r};ImageBuffer.unpackPixel=function(rgba,out){if(!out)out={r:0,g:0,b:0,a:0};out.a=(rgba&4278190080)>>>24;out.b=(rgba&16711680)>>>16;out.g=(rgba&65280)>>>8;out.r=rgba&255;return out}}else{ImageBuffer.packPixel=function(r,g,b,a){return r<<24|g<<16|b<<8|a};ImageBuffer.unpackPixel=function(rgba,out){if(!out)out={r:0,g:0,b:0,a:0};out.r=(rgba&4278190080)>>>24;out.g=(rgba&16711680)>>>16;out.b=(rgba&65280)>>>8;out.a=rgba&255;return out}}ImageBuffer.fromRGBA=function(rgba,out){if(!out)out={r:0,g:0,b:0,a:0};out.r=(rgba&4278190080)>>>24;out.g=(rgba&16711680)>>>16;out.b=(rgba&65280)>>>8;out.a=rgba&255;return out};ImageBuffer.toRGBA=function(r,g,b,a){return r<<24|g<<16|b<<8|a};ImageBuffer.createColor=function(r,g,b,a){return{r:r||0,g:g||0,b:b||0,a:a||0}};module.exports=ImageBuffer},{}]},{},[1])(1)});
//our direct manipulation buffer...
var buffer = new ImageBuffer(imageData);
ctx.putImageData(imageData, 0, 0);
Ready to run.
Test | Ops/sec | |
---|---|---|
8-bit Pixel Manipulation |
| ready |
32-bit Pixel Manipulation |
| ready |
imagebuffer-test |
| ready |
imagebuffer-manual |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.