This isn't something that I'm sure would be worth adding to Espruino core, as Math.sin itself should be reasonably fast compared to general JS execution speed. For example:
function go() {
var t = getTime();
for (var i=0;i<1000;i++) Math.sin(i);
print("sin ",getTime()-t);
var t = getTime();
for (var i=0;i<1000;i++) Math.abs(i);
print("abs ",getTime()-t);
}
>go()
sin 0.45587158203
abs 0.41012573242
So even if I could make it as fast as abs, it's only going to shave 10% off the time - if that.
However nothing stops you from doing it yourself (or just finding ways to improve the speed of the loop). As an example:
var a = new Uint8ClampedArray(250*3);
function getColours(arr,r,g,b) {
for (var i=0;i<750;i+=3) {
arr[i ] = 128+128*Math.sin(r+i);
arr[i+1] = 128+128*Math.sin(g+i*2);
arr[i+2] = 128+128*Math.sin(b+i*3);
}
}
function getColoursCompiled(arr,r,g,b) {
"compiled";
for (var i=0;i<750;i+=3) {
arr[i ] = 128+128*Math.sin(r+i);
arr[i+1] = 128+128*Math.sin(g+i*2);
arr[i+2] = 128+128*Math.sin(b+i*3);
}
}
// Sum all items in the given array
var c = E.compiledC(`
// void getColours(int, int, int)
void getColours(unsigned char *data, int ai, int ar){
int pr = 65535;
int pi = 0;
for (int i=0;i<750;i++) {
int temp = ((pr * ai) - (pi * ar)) >> 16;
pi = ((pr * ar) + (pi * ai)) >> 16;
pr = temp;
*(data++) = pr>>8;
}
}
`);
function test() {
var i,t;
t = getTime();
for (i=0;i<10;i++) getColours(a,0,0,0);
print("normal ",(getTime()-t)/10);
t = getTime();
for (i=0;i<10;i++) getColoursCompiled(a,0,0,0);
print("compiled ",(getTime()-t)/10);
// Get the address
var addr = E.getAddressOf(a,true);
if (!addr) throw new Error("Not a Flat String");
var ang = 0.1;
t = getTime();
for (i=0;i<10;i++) c.getColours(addr,65536*Math.cos(ang),65536*Math.sin(ang));
print("inline C ",(getTime()-t)/10);
}
>test()
normal 0.55126647949
compiled 0.19281005859
inline C 0.00126647949
So a compiled version of exactly the same code is almost 3 times as fast. What's stopping it going much faster is actually all the double arithmetic.
However inline C using integers and your oscillator example is brutally fast (400x more than normal JS).
Thing is, if you just used inline C for your oscillator, those gains would get wiped out by the JS execution speed, so you really need to keep the whole thing in C to get the improvements.
Espruino is a JavaScript interpreter for low-power Microcontrollers. This site is both a support community for Espruino and a place to share what you are working on.
This isn't something that I'm sure would be worth adding to Espruino core, as
Math.sin
itself should be reasonably fast compared to general JS execution speed. For example:So even if I could make it as fast as
abs
, it's only going to shave 10% off the time - if that.However nothing stops you from doing it yourself (or just finding ways to improve the speed of the loop). As an example:
So a compiled version of exactly the same code is almost 3 times as fast. What's stopping it going much faster is actually all the double arithmetic.
However inline C using integers and your oscillator example is brutally fast (400x more than normal JS).
Thing is, if you just used inline C for your oscillator, those gains would get wiped out by the JS execution speed, so you really need to keep the whole thing in C to get the improvements.
Hope that helps!