javascript - Why is multiple inline IFs faster than a loop with one IF per array entry -


angular has following interesting function implementation instead of looping through array of values takes them parameters , performs if checks inline. assumed done performance purposes created this simple performance test:

function checkandupdatetextinline(v, def, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {     let changed = false;     const bindings = def.bindings;     const bindlen = bindings.length;      if (bindlen > 0 && checkandupdatebinding(v, def, 0, v0)) changed = true;     if (bindlen > 1 && checkandupdatebinding(v, def, 1, v1)) changed = true;     if (bindlen > 2 && checkandupdatebinding(v, def, 2, v2)) changed = true;     if (bindlen > 3 && checkandupdatebinding(v, def, 3, v3)) changed = true;     if (bindlen > 4 && checkandupdatebinding(v, def, 4, v4)) changed = true;     if (bindlen > 5 && checkandupdatebinding(v, def, 5, v5)) changed = true;     if (bindlen > 6 && checkandupdatebinding(v, def, 6, v6)) changed = true;     if (bindlen > 7 && checkandupdatebinding(v, def, 7, v7)) changed = true;     if (bindlen > 8 && checkandupdatebinding(v, def, 8, v8)) changed = true;     if (bindlen > 9 && checkandupdatebinding(v, def, 9, v9)) changed = true;      return changed; } 

versus dynamic version:

function checkandupdatetextdynamic(v, def, values) {     const bindings = def.bindings;     let changed = false;     (let = 0; < values.length; i++) {         if (checkandupdatebinding(v, def, i, values[i])) {             changed = true;         }     } } 

and inline version seems 25% faster dynamic. reason that? inline caching in play here? how can debug using d8?

first, 2 versions not equivalent: number of iterations bounded bindings.length in first , values.length in second. if differ, may different number of iterations.

second, there several operations unrolled version avoids:

  • getting values.length on every iteration.
  • accessing values[i] on every iteration.
  • reading i on every iteration.
  • incrementing i on every iteration.
  • jumping beginning of loop every iteration.

the first 2 in particular can expensive, depending on amount of dynamic optimisations , specialisation compiler able perform. , if checkandupdatebinding doesn't much, might noticeable overhead. try change original version use of these operations well, , see puts in comparison.

third, micro benchmark. performance in javascript involves many hidden variables , dependencies on static , dynamic context micro benchmarks more pointless measure other languages. in general, estimate 90% of people measure on jsperf useless or misleading.

fourth, note loop unrolling common optimisation performed compilers. in cases can significant win, in languages more efficient javascript.


Comments