If you're doing lots of string concatenation and then writing that string somewhere, you may find that passing your string through
flatstrvastly improves performance.
var flatstr = require('flatstr') flatstr(someHeavilyConcatenatedString)
Benchmarks test flat vs non-flat strings being written to an
unflattenedManySmallConcats*10000: 147.540ms flattenedManySmallConcats*10000: 105.994ms unflattenedSeveralLargeConcats*10000: 287.901ms flattenedSeveralLargeConcats*10000: 226.121ms unflattenedExponentialSmallConcats*10000: 410.533ms flattenedExponentialSmallConcats*10000: 219.973ms unflattenedExponentialLargeConcats*10000: 2774.230ms flattenedExponentialLargeConcats*10000: 1862.815ms
In each case, flattened strings win, here's the performance gains from using
ManySmallConcats: 28% SeveralLargeConcats: 21% ExponentialSmallConcats: 46% ExponentialLargeConcats: 33%
V8 has a a method called
String::Flattenwhich converts the tree into a C array. This method is typically called before operations that walk through the bytes of the string (for instance, when testing against a regular expression). It may also be called if a string is accessed many times over, as an optimization on the string. However, strings aren't always flattened. One example is when we pass a string into a
WriteStream, at some point the string will be converted to a buffer, and this may be expensive if the underlying representation is a tree.
There are several ways to indirectly call
alt-benchmark.js), but coercion to a number appears to be (one of) the cheapest.
However since Node 10 the V8 version has stopped using Flatten in all places identified. Thus the code has been updated to seamlessly use the native runtime function
%FlattenStringwithout having to use the
One final note: calling flatstr too much can in fact negatively effect performance. For instance, don't call it every time you concat (if that was performant, v8 wouldn't be using trees in the first place). The best place to use flatstr is just prior to passing it to an API that eventually runs non-v8 code (such as
fs.WriteStream, or perhaps
xhror DOM apis in the browser).