Last active
March 12, 2020 13:58
-
-
Save 3v1n0/7c2c162224358088b5122f16ce379dc8 to your computer and use it in GitHub Desktop.
ARGB to RGBA conversion tests in Javascript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function argbToRgba(src, inline=false) { | |
let dest = inline ? src : new Uint8Array(src.length); | |
let srcView = new DataView(src.buffer); | |
let destView = new DataView(dest.buffer); | |
for (let i = 0; i < src.length; i += 4) { | |
let argb = srcView.getUint32(i); | |
let rgba = (argb & 0x00FFFFFF) << 8 | | |
(argb & 0xFF000000) >>> 24; | |
destView.setUint32(i, rgba); | |
} | |
return dest; | |
} | |
function argbToRgbaInline(src) { | |
return argbToRgba(src, true); | |
} | |
function argbToRgbaSimple(src, inline=false) { | |
let dest = inline ? src : new Uint8Array(src.length); | |
for (let i = 0; i < src.length; i += 4) { | |
let a = src[i] | |
let r = src[i + 1] | |
let g = src[i + 2] | |
let b = src[i + 3] | |
dest[i] = r; | |
dest[i + 1] = g; | |
dest[i + 2] = b; | |
dest[i + 3] = a; | |
} | |
return dest; | |
} | |
function argbToRgbaSimpleInline(src) { | |
return argbToRgbaSimple(src, true); | |
} | |
function argbToRgbaSimpleNoVars(src, inline = false) { | |
let dest = inline ? src : new Uint8Array(src.length); | |
for (let i = 0; i < src.length; i += 4) { | |
let a = src[i] | |
dest[i] = src[i + 1]; | |
dest[i + 1] = src[i + 2]; | |
dest[i + 2] = src[i + 3]; | |
dest[i + 3] = a; | |
} | |
return dest; | |
} | |
function argbToRgbaSimpleNoVarsInline(src) { | |
return argbToRgbaSimpleNoVars(src, true); | |
} | |
// From https://stackoverflow.com/a/60639510/210151 | |
function argb2rgbaStackOverflow(inArr) { | |
return inArr.reduce((a, c, i, t) => { | |
if (i % 4 === 0) { | |
let [A, R, G, B] = t.slice(i, i + 4) | |
a.push(R, G, B, A) | |
} | |
return a | |
}, []) | |
} | |
function measureFunction(func) { | |
let preTime = new Date().getTime(); | |
let ret = func.call(...arguments); | |
console.log(`Calling ${func.name} took ${new Date().getTime() - preTime}ms`); | |
return ret; | |
} | |
function createRandomArray(size) { | |
return new Uint8Array(size).fill().map((a, i) => | |
a = i).sort(() => Math.random() - 0.5); | |
} | |
// In bytes | |
const bigSize = 4 * 1024 * 1024; | |
function iconSizeToBytes(iconSize) { | |
const bytesPerPixel = 4; | |
return iconSize * iconSize * bytesPerPixel; | |
} | |
// This is to add support to console.log to gjs | |
try { | |
console; | |
} catch(e) { | |
window.console = { | |
log: function() { print(...arguments) }, | |
}; | |
} | |
let allSizes = [ | |
bigSize, | |
iconSizeToBytes(32), | |
iconSizeToBytes(64), | |
iconSizeToBytes(512), | |
]; | |
for (let size of allSizes) { | |
console.log(`Creating random array of ${size/(1024 * 1024)}Mbyte...`); | |
let randomArray = measureFunction(createRandomArray, size); | |
measureFunction(argbToRgba, randomArray); | |
measureFunction(argbToRgbaInline, randomArray); | |
measureFunction(argbToRgbaSimple, randomArray); | |
measureFunction(argbToRgbaSimpleInline, randomArray); | |
measureFunction(argbToRgbaSimpleNoVars, randomArray); | |
measureFunction(argbToRgbaSimpleNoVarsInline, randomArray); | |
measureFunction(argb2rgbaStackOverflow, randomArray); | |
console.log(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Results with
gjs
1.58So the one that apparently should be more optimized (
argbToRgbaInline
) actually is not.