title: Writing high-performance Javascript code without getting deoptimised
body: <p>When writing performance-sensitive code in Javascript which operates on large numeric arrays (think a linear algebra package, operating on integers or floating-point numbers), one always wants the the JIT to help out as much as possible. Roughly this means:</p>
  
  <ol>
  <li>We always want our arrays to be packed SMIs (small integers) or packed Doubles, depending on whether we're doing integer or floating-point calculations.</li>
  <li>We always want to be passing the same type of thing to functions, so that they don't get labelled "megamorphic" and deoptimised. For instance, we always want to be calling <code>vec.add(x, y)</code> with both <code>x</code> and <code>y</code> being packed SMI arrays, or both packed Double arrays.</li>
  <li>We want functions to be inlined as much as possible.</li>
  </ol>
  
  <p>When one strays outside of these cases, a sudden and drastic performance dropoff occurs. This can happen for various innocuous reasons:</p>
  
  <ol>
  <li>You might turn a packed SMI array into a packed Double array via a seemingly innocuous operation, like the equivalent of <code>myArray.map(x =&gt; -x)</code>. This is actually the "best" bad case, since packed Double arrays are still very fast.</li>
  <li>You might turn a packed array into a generic boxed array, for example by mapping the array over a function which (unexpectedly) returned <code>null</code> or <code>undefined</code>. This bad case is fairly easy to avoid.</li>
  <li>You might deoptimise a whole function such as <code>vec.add()</code> by passing in too many types of things and turning it megamorphic. This could happen if you want to do "generic programming", where <code>vec.add()</code> is used both in cases where you're not being careful about types (so it sees a lot of types come in) and in cases where you want to eke out maximum performance (it should only ever receive boxed doubles, for instance).</li>
  </ol>
  
  <p>My question is more of a soft question, about how one writes high-performance Javascript code in light of the considerations above, while still keeping the code nice and readable. Some specific sub-questions so that you know what kind of answer I'm aiming for:</p>
  
  <ul>
  <li>Is there a set of guidelines somewhere on how to program while staying in the world of packed SMI arrays (for instance)?</li>
  <li>Is possible to do generic high-performance programming in Javascript without using something like a macro system to inline things like <code>vec.add()</code> into callsites?</li>
  <li>How does one modularise high-performance code into libaries in light of things like megamorphic call sites and deoptimisations? For instance, if I am happily using Linear Algebra package <code>A</code> at high speed, and then I import a package <code>B</code> that depends on <code>A</code>, but <code>B</code> calls it with other types and deoptimises it, suddenly (without my code changing) my code runs slower.</li>
  <li>Are there any good <em>easy to use</em> measurement tools for checking what the Javascript engine is doing internally with types?</li>
  </ul>