Optimize Js_of_ocaml function call

Hi!,

I’m trying to convince Js_of_ocaml to generate some faster code for a function call. Right now it’s generating calls to caml_call1 which seems to be pretty slow because it checks f.length. Is there any way I can add an annotation or change the code to convince Js_of_ocaml to do a direct application f(a) instead of going through caml_call? The usage sites are all non-curried functions.

caml_call looks like:

    function caml_call1(f,a0)
     {return f.length == 1?f(a0):caml_call_gen(f,[a0])}

and the function that’s using caml_call is an iteration function for a collection:

let iter (t : 'a t) ~(f : 'a -> unit) : unit =
    let len = t.size-1 in
    for i=0 to len do
        f (Array.unsafe_get t.arr i)
    done

generated js:

    function iter$4(t,f)
     {var len=t[3] - 1 | 0,_zv_=0;
      if(! (len < 0))
       {var i=_zv_;
        for(;;)  
         {caml_call1(f,t[2][1 + i]);
          var _zw_=i + 1 | 0;
          if(len !== i){var i=_zw_;continue}
          break}}   
      return 0}  

And as a follow-up are there general rules for when Js_of_ocaml applies certain optimizations? I’ve noticed that functors cause it to deoptimize things a bit, and sometimes adding an annotation might generate better code.

Thank you!

2 Likes