> But [the strcmp] is there, and a string comparison will usually (but not always) require comparing each of the characters in the string with the ones in the other string<p>This is not true in anything except for toy interpreters, for a number of reasons.<p>One, internally strings are stored alongside the length. For 'TOP' and 'BOTTOM' the lengths don't match which means the strings can't be equal. That means inequality testing requires only a single integer comparison.<p>Two, strcmp is used for ordering strings, that's why it returns -1, 0, 1. That additional work isn't needed for testing equality. JS engines are not going to call strcmp unnecessarily.<p>Three, modern Javascript engines don't treat all strings the same. There are fast paths for ASCII strings, for interned strings, for concatenated strings, for strings that are slices of other strings, and more. From the perspective of the programmer a Javascript string is just a string. In reality a string in Javascript is nothing like C's char*.<p>I suspect -- but don't actually know -- that the string compare in the benchmark of example 1 is slower because the JS engine has to do a type check on the internal string representation. That's an extra branch the integer path doesn't need.
Loved this write up. Of course the usual caveats with this level of optimization apply, and in general we should be aiming to optimize for human readability. But if nothing else I think it’s a good thing to get a better internal understanding of how the interpreter works.<p>With that in mind, it’d be interesting to see the relative costs of each deoptimization to the others. For example, is a monomorphic->polymorphic deopt an order of magnitude worse than an unnecessary string mutation? In nanoseconds, what’s the actual cost of each of these? Because there are certainly going to be some optimizations that matter much more than others.
Lots of good points here. The problem with JS optimization is that, as developers, we are basically flying blind.<p>Looking into how to get more debugging information out of a JS engine, I found this V8 blogpost that explains how to install a debugging version of V8 called "D8" [1].<p>I wish getting debug info was way easier though. Imagine being able to do something like this:<p><pre><code> function xyz() { "use debug"; }</code></pre>
--<p>1: <a href="https://v8.dev/blog/elements-kinds#debugging" rel="nofollow">https://v8.dev/blog/elements-kinds#debugging</a>
For the functional vs imperative... Why make the example array.map.filter.reduce rather than just a single reduce? I find map.filter.reduce to be a gross anti pattern.