Speedy for Espruino

Posted on
  • During my test with a driver for LED panel, @Gordon added a very nice speed up function.

    This looks very good, and I gave it a chance to become a seperate function. In first test, it even speeds up bit.
    @Gordon, usually you have some good ideas. Could this be a starting point for a kind of prebind, not saying precompile ?

    void jswrap_espruino_speedy_callback(int val, void *data){
      JsVar *fnc = (JsVar*)data;
      JsVar *value = jsvNewFromInteger(val);
      if(jsvIsFunction(fnc)) jspExecuteFunction(fnc,0,1,&value);
      jsvUnLock(value);
    }
    void jswrap_espruino_speedy(JsVar *arrayFunction, JsVar *arr){
      jsvIterateCallback(arr,jswrap_espruino_s­peedy_callback, arrayFunction);
    }
    
  • Is this significantly faster than something like forEach - which should ideally do basically the same thing:

    a = new Uint8Array(1000);
    a.forEach(callbackFn);
    

    I'd have hoped that they would be quite similar. If not, it's probably something I should look at performance-wise :)

  • The idea behind speedy is slightly different.
    forEach is running with one callbackFn only.
    Idea is to combine different functions with a default function.
    Thats close to your changes to shiftOut.
    in this example we combine a simple console.log with pin.set/reset

    function fill(){
      arr = [];
      arr.push({callback:en.reset.bind(en)});
      arr.push({callback:console.log.bind(cons­ole,"qwertz\n")});
      arr.push({callback:en.set.bind(en)});
      arr.push({callback:console.log.bind(cons­ole,"asdf\n")});
      arr.push([1,3,5]);
      arr.push("abc");
    }
    
    x = console.log.bind(console,"z:");
    function speed(n){
      fill();
      if(!n) n = 100;
      var t = getTime();
      for(var i = 0; i < n; i++) E.speedy(x,arr);
      console.log(getTime() -t);
    }
    
    

    I would not say, this is standard Javascript ;-), it could be helpful, but is it worth it ?

  • Ahh, ok - so being able to execute an array of functions one after the other?

    Something like this is actually very close to doing exactly what you want:

    arr = [];
    arr.push({callback:console.log.bind(cons­ole,"qwertz\n")});
    E.toUint8Array(arr)
    

    However because it runs through once to count the elements it actually ends up calling everything twice. I guess a E.count(...) would actually serve two purposes.

    But does anyone else have any thoughts about whether this would get used?

    Personally it feels like a very niche thing and I'm not too sure of the uses. I mean, if eval allowed you to pass in a function then you could just do arr.forEach(eval) for a (probably faster) effect... and on a lot of platforms just doing:

    function go() {
      "compiled";
      en.reset();
      console.log("qwertz\n");
      en.set();
      console.log("asdf\n");
    }
    

    would be more readable and significantly faster.

    To be honest the best thing would be to just make the interpreter itself able to 'fast path' simple JavaScript functions so they executed extremely quickly - then we wouldn't need a lot of this messing around.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Speedy for Espruino

Posted by Avatar for JumJum @JumJum

Actions