Fast cos tests
Fast cos tests
by Csaba Hellinger
HTML
<div>
<canvas id="canvas1" width="2000" height="2000"></canvas>
<canvas id="canvas2" width="2000" height="2000"></canvas>
<canvas id="canvas3" width="2000" height="2000"></canvas>
</div>
CSS
div {
display:grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 0.5rem;
}
canvas {
width: 100%;
background: pink;
}
body {
background: #222;
}
JavaScript
const PI = Math.PI;
const draw = (canvasId, cos, name) => {
const canvas = document.getElementById(canvasId);
const context = canvas.getContext('2d');
const imageData = context.getImageData(0,0,canvas.width, canvas.height);
const data = imageData.data;
const S = Math.max(canvas.width, canvas.height);
const start = performance.now();
for (let y=0; y<S; y+=1) {
for (let x=0; x<S; x+=1) {
const i = (y * S + x) * 4;
data[i + 0] = Math.trunc((cos(2*PI/S*x*3+PI) + cos(2*PI/S*y+PI)) * 128);
data[i + 1] = Math.trunc((cos(2*PI/S*x*2 ) + cos(2*PI/S*y*2 )) * 128);
data[i + 2] = Math.trunc((cos(2*PI/S*x +PI) + cos(2*PI/S*y )*2) * 128);
data[i + 3] = 255;
}
}
console.log(name, performance.now()-start);
context.putImageData(imageData, 0, 0);
};
draw('canvas1', Math.cos, 'Math.cos');
const lookup = Array(360).fill(0).map((_,i) => Math.cos(PI/180*i));
const fastCos2 = rad => lookup[Math.trunc(rad / PI * 180) % 360];
const fastCos3 = rad => lookup[~~(rad / PI * 180) % 360];
const fastCos4 = rad => lookup[~~(rad / radToDeg) % 360];
const radToDeg = PI / 180;
draw('canvas2', fastCos4, 'fastCos4');
//const lookup2 = Array(629).fill(0).map((_,i) => Math.cos(i*0.01));
//const fastCos5 = rad => lookup2[~~((rad % (2*PI)) * 100)];
const TABLE_SIZE = 256; // power of two
const INDEX_FACTOR = TABLE_SIZE / (2 * PI); // scale radians to table index
const lookup2 = Array(TABLE_SIZE).fill(0).map((_, i) => Math.cos(i / INDEX_FACTOR));
const fastCos5 = rad => lookup2[(rad * INDEX_FACTOR) & (TABLE_SIZE - 1)];
draw('canvas3', fastCos5, 'fastCos5');