-
Notifications
You must be signed in to change notification settings - Fork 197
Closed
Labels
Description
In the same way as caml_js_new, one could add fast paths in caml_js_fun_call and other similar functions to avoid copying the array of arguments:
function caml_js_fun_call(f, args) {
switch (args.length) {
case 1: return f.call(null);
case 2: return f.call(null, args[1]);
case 3: return f.call(null, args[1], args[2]);
case 4: return f.call(null, args[1], args[2], args[3]);
// ad libitum
}
return f.apply(null, caml_js_from_array(args));
}
The compiler could also detect cases where caml_js_fun_call is called on an array of known size to inline the corresponding branch directly. Or, alternatively, one could expose specialized primitives caml_js_fun_call1, caml_js_fun_call2.
The micro-benchmark below runs about 15x faster with the version of caml_js_fun_call above.
let () =
let r = ref [| Js.Unsafe.inject 1 |] in
for i = 1 to 10000000 do
if i < 1 then r := [| Js.Unsafe.inject 0 |]; (* prevent wrong optim *)
Js.Unsafe.fun_call (Js.Unsafe.variable "add") !r;
done
<script type="text/javascript">
var accu = 0;
function add(x) { accu += x; }
var t0 = new Date().getTime();
</script>
<script type="text/javascript" src="bench_js.js">
</script>
<script type="text/javascript">
var t1 = new Date().getTime();
alert("Sum = " + accu + "\nTime : " + (t1 - t0));
</script>