You are reading a single comment by @Gordon and its replies. Click here to read the full conversation.
  • 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.

    Hope that helps!

About

Avatar for Gordon @Gordon started