Does the compiled output influence the performance?

I have some part of the code in raw js.

function make(buf) {
  var p = 0
  if (buf[p++] !== 0x47 ||
      buf[p++] !== 0x49 ||
      buf[p++] !== 0x46 ||
      buf[p++] !== 0x38
 ) {
  throw new Error(`invalid buffer`)
}
}

I rewrite it in rescript

let p = ref(0)
  @inline
  let autoIncrement = () => {
    let pv = p.contents
    p := p.contents + 1
    pv
  }
  if buf->Js.TypedArray2.Uint8Array.unsafe_get(autoIncrement()) !== 0x47 ||
    buf->Js.TypedArray2.Uint8Array.unsafe_get(autoIncrement()) !== 0x49 ||
    buf->Js.TypedArray2.Uint8Array.unsafe_get(autoIncrement()) !== 0x46 ||
    buf->Js.TypedArray2.Uint8Array.unsafe_get(autoIncrement()) !== 0x38 
  {
      Js.Exn.raiseError(`Invalid`)
    }

The compiled output is below:

// Generated by ReScript, PLEASE EDIT WITH CARE
'use strict';

var Js_exn = require("rescript/lib/js/js_exn.js");

function make(buf) {
  var p = 0;
  var pv = p;
  p = p + 1 | 0;
  var tmp = true;
  if (buf[pv] === 71) {
    var pv$1 = p;
    p = p + 1 | 0;
    tmp = buf[pv$1] !== 73;
  }
  var tmp$1 = true;
  if (!tmp) {
    var pv$2 = p;
    p = p + 1 | 0;
    tmp$1 = buf[pv$2] !== 70;
  }
  var tmp$2 = true;
  if (!tmp$1) {
    var pv$3 = p;
    p = p + 1 | 0;
    tmp$2 = buf[pv$3] !== 56;
  }
  if (tmp$2) {
    return Js_exn.raiseError("Invalid");
  }
}

exports.make = make;
/* No side effect */

As you can see, there are a lot of temporary variables generated by the compiler. Does this will slow the program?

No, if it’s a primitive there’s almost no difference. ReScript compiler generates quite optimized code, so you shouldn’t worry about it.

1 Like

This is just a part of my code. The function make will be called many times, i just want to know will lots of temporary variables make the program slower than the raw js which only use p++.

I use this to walk around it, don’t know if it is meaningful.

let make = buf => {
  %raw(`var p = 0`)->ignore
  @inline
  let autoIncrement = () => {
    %raw(`p++`)
  }
  if buf->Js.TypedArray2.Uint8Array.unsafe_get(autoIncrement()) !== 0x47 ||
    buf->Js.TypedArray2.Uint8Array.unsafe_get(autoIncrement()) !== 0x49 ||
    buf->Js.TypedArray2.Uint8Array.unsafe_get(autoIncrement()) !== 0x46 ||
    buf->Js.TypedArray2.Uint8Array.unsafe_get(autoIncrement()) !== 0x38 
  {
      Js.Exn.raiseError(`Invalid.`)
    }
}

The compiled js is below:

// Generated by ReScript, PLEASE EDIT WITH CARE
'use strict';

var Js_exn = require("rescript/lib/js/js_exn.js");

function make(buf) {
  ((var p = 0));
  if (buf[(p++)] !== 71 || buf[(p++)] !== 73 || buf[(p++)] !== 70 || buf[(p++)] !== 56) {
    return Js_exn.raiseError("Invalid.");
  }
  
}

exports.make = make;
/* No side effect */

The assignment to a variable almost diesn’t affect performance, what could cause a problem is | 0 when summing integers. But it’s still not more than few nanoseconds.
The best option is to get rid of p++ completely https://rescript-lang.org/try?code=DYUwLgBAtghg1iCBeCAjArgM2QPggbwCgIIBLbACmJLSwFocApAZwDoAVATwAcQATAIIAnITE4AmVgFVSAOzAAOYaM6t0s5jEwgA+gHNwFAAwBKCAEIkKIwA8ALAHYIAH2fUSGTAxYce-ZWKSMvJKImJqGlq6BmAUAIxmltb2AJwubjS0XkxsXLyCYRLScooBquqa2vqG4olWELZ2AGzp7lneuX4FKkEloSoRldGGAMx1ySMK1GZEmT4AojayrKKkzCDzIgD2QhQABgCSsgBuMMCkfHsm1AC+hHdAA

1 Like

I would be very careful about making assumptions about performance without actually measuring it. JS performance is often not intuitive and can vary from engine to engine. Also, if you’re running your code through a minifier, then it’s likely that some of those temporary variables will get optimized away anyway.

2 Likes

I did a lot of measurements recently, while working on the rescript-struct, so I have a gist of how certain code might affect performance.

2 Likes

I don’t doubt that you’re correct. :slightly_smiling_face: I just meant that as a disclaimer for anyone else reading this and curious about performance in general. If you ever wonder “does X influence performance” then the best thing to do is measure it.

2 Likes

Totally agree. Alot of my assumptions happened to be wrong, after I actually measured them.