Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

const vs inline string literal, compilation optimisation

This is question is not an issue, but rather an exploration of V8 optimisations based on code structure.


Another developer and I are debating the value of const string literal vs inline string literal on V8's compilation optimisations. Assume we're always in strict mode, of course.

Here are some code examples to put in context:

const

const NAME = "something";
function doSomething(s) {
  return NAME + s;
}

vs

inline string

function doSomething(s) {
  return "something" + s;
}

What we agree on:
- const provides more context to magic values, which eases maintenance.

What we disagree on:

  • I say that the use of const allows V8 to make compile-time optimisations to your code because of the assurance that the constant value cannot change.

  • He says that an inline-string litteral is identical (if not better, because of reduced indirection) for the V8 compiler. Because the same optimisations can be equally applied when referencing such an inline string.

Giving it a bit of thought I would tend to agree with him... The string literal would be re-instantiated every time the function is called, but that can easily be optimised by V8 and avoided for subsequent calls. However, I'm not all that knowledgeable on compilers and compiler optimisations.

Can anyone shed some light on this?

like image 601
Sebastien Daniel Avatar asked Jan 19 '17 13:01

Sebastien Daniel


1 Answers

V8 developer here.

The inline string is shared across all function invocations even in unoptimized code, so no need to worry about re-instantiations. Generally, it's trivial for a JS engine to figure out that literals never change (because they're literals, duh!). A const does not provide as many guarantees as you'd think, because JavaScript is complicated (example:

function makeFunction(val) { 
  const NAME = val; 
  function doSomething(s) { 
    return NAME + s;
  }
  return doSomething;
}
var doSomething = makeFunction("something");
var doAnything = makeFunction("anything, really");

Here,const NAME is not quite what you'd intuitively call a constant ;-) ).

That said, the difference between the two approaches is probably too small to matter. Do whatever makes more sense in your code.


Side note: things would be different for more complicated objects than strings or numbers. E.g. this:

function getSomething() { return "something"; }
function doSomething(s) { return getSomething() + s; }

is clearly more efficient than this:

function doSomething(s) {
  function getSomething() { return "something"; }
  return getSomething() + s;
}

because in that case, a JS engine has to create fresh instances of "getSomething" (or spend a lot of implementation+computation effort on figuring out that doing so can be avoided; I wouldn't rely on that). The difference is due to observability of object identity:

"a" === "a"  // true
(function f() {}) === (function f() {})  // false
like image 149
jmrk Avatar answered Nov 16 '22 11:11

jmrk