npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

flatstr

v1.0.12

Published

Flattens the underlying C structures of a concatenated JavaScript string

Downloads

7,103,246

Readme

flatstr

Flattens the underlying C structures of a concatenated JavaScript string

About

If you're doing lots of string concatenation and then writing that string somewhere, you may find that passing your string through flatstr vastly improves performance.

Usage

var flatstr = require('flatstr')
flatstr(someHeavilyConcatenatedString)

Benchmarks

Benchmarks test flat vs non-flat strings being written to an fs.WriteStream.

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 flatstr

ManySmallConcats: 28%
SeveralLargeConcats: 21% 
ExponentialSmallConcats: 46%
ExponentialLargeConcats: 33%

How does it work

In the v8 C++ layer, JavaScript strings can be represented in two ways.

  1. As an array
  2. As a tree

When JavaScript strings are concatenated, tree structures are used to represent them. For the concat operation, this is cheaper than reallocating a larger array. However, performing other operations on the tree structures can become costly (particularly where lots of concatenation has occurred).

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.

String::Flatten is not exposed as a JavaScript function, but it can be triggered as a side effect.

There are several ways to indirectly call String::Flatten (see 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 %FlattenString without having to use the --allow-natives-syntax flag directly.

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 xhr or DOM apis in the browser).

Acknowledgements

  • Sponsored by nearForm

License

MIT