83

GitHub - vzhou842/faster.js: faster.js is a Babel plugin that compiles idiomatic...

 6 years ago
source link: https://github.com/vzhou842/faster.js
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

README.md

NPM Version Build Status

faster.js

faster.js is a Babel plugin that compiles idiomatic Javascript to faster, micro-optimized Javascript using ideas inspired by the fast.js library.

Installation

Setup Babel for your project if you haven't already. Then install faster.js:

npm install --save-dev faster.js

Usage

.babelrc
{
  "plugins": ["faster.js"]
}
Babel CLI
babel-cli --plugins faster.js script.js
webpack.config.js (Webpack 4)
module: {
  rules: [{
    test: /\.js$/,
    exclude: /(node_modules)/,
    use: {
      loader: 'babel-loader',
      options: {
        plugins: [require('faster.js')]
      }
    }
  }]
}

What faster.js does

faster.js rewrites common Array method calls to faster code that does the same thing (usually - see When NOT to use faster.js). This results in performance boosts (especially on code that relies heavily on Array methods) while maintaining code readability, but comes at the cost of a slightly larger bundle size. If having a small Javascript bundle size is much more important for you than performance is, you should not use faster.js.

Supported Array methods

faster.js will rewrite the following Array methods when possible:

  • .every()
  • .filter()
  • .forEach()
  • .map()
  • .reduce()
  • .reduceRight()
  • .some()

Demo

faster.js Demo Screenshot

Try it yourself: https://fasterjs-demo.victorzhou.com

Demo Github repo: https://github.com/vzhou842/faster.js-demo

⚠️ When NOT to use faster.js

faster.js makes two critical assumptions that MUST be true about your codebase:

1. Sparse Arrays are never used.

Code compiled with faster.js may produce incorrect results when run on sparse arrays.

2. Restricted methods are only ever called on native Javascript arrays:

faster.js assumes any restricted method call is done on a native Javascript array. Any new classes you write should not include methods with restricted names.

Restricted method names are the names of methods that faster.js will attempt to rewrite - see Supported Array methods.

// OK
const a = [1, 2, 3].map(e => 2 * e);

// BAD
class Foo {
  constructor(map) {
    this._map = map;
  }
  map() {
    return this._map;
  }
}
const f = new Foo({});
const map = f.map(); // .map() is a restricted method

How faster.js works

faster.js exploits the fact that native Javascript Array methods are slowed down by having to support seldom-used edge cases like sparse arrays. Assuming no sparse arrays, there are often simple ways to rewrite common Array methods to improve performance.

Example: Array.prototype.forEach()

// Original code
const arr = [1, 2, 3];
const results = arr.map(e => 2 * e);

roughly compiles to

// Compiled with faster.js
const arr = [1, 2, 3];
const results = [];
const _f = (e => 2 * e);
for (let _i = 0; _i < arr.length; _i++) {
  results.push(_f(arr[_i], _i, arr));
}

Benchmarks

Example benchmark output (condensed)

$ npm run bench

  array-every large
    ✓ native x 2,255,548 ops/sec ±0.46% (57 runs sampled)
    ✓ faster.js x 10,786,892 ops/sec ±1.25% (56 runs sampled)
faster.js is 378.2% faster (0.351μs) than native

  array-filter large
    ✓ native x 169,237 ops/sec ±1.42% (55 runs sampled)
    ✓ faster.js x 1,110,629 ops/sec ±1.10% (59 runs sampled)
faster.js is 556.3% faster (5.008μs) than native

  array-forEach large
    ✓ native x 61,097 ops/sec ±3.66% (43 runs sampled)
    ✓ faster.js x 200,459 ops/sec ±0.52% (55 runs sampled)
faster.js is 228.1% faster (11.379μs) than native

  array-map large
    ✓ native x 169,961 ops/sec ±1.51% (57 runs sampled)
    ✓ faster.js x 706,781 ops/sec ±0.64% (59 runs sampled)
faster.js is 315.8% faster (4.469μs) than native

  array-reduce large
    ✓ native x 200,425 ops/sec ±1.01% (55 runs sampled)
    ✓ faster.js x 1,694,350 ops/sec ±1.52% (55 runs sampled)
faster.js is 745.4% faster (4.399μs) than native

  array-reduceRight large
    ✓ native x 49,784 ops/sec ±0.38% (58 runs sampled)
    ✓ faster.js x 1,756,352 ops/sec ±0.99% (59 runs sampled)
faster.js is 3428.0% faster (19.517μs) than native

  array-some large
    ✓ native x 2,968,367 ops/sec ±0.56% (56 runs sampled)
    ✓ faster.js x 11,591,773 ops/sec ±1.29% (54 runs sampled)
faster.js is 290.5% faster (0.251μs) than native

FAQ

What is a sparse array?

Sparse arrays are arrays that contain holes or empty slots.

const sparse1 = [0, , 1]; // a sparse array literal
console.log(sparse1.length); // 3

const sparse2 = [];
sparse2[5] = 0; // sparse2 is now a sparse array
console.log(sparse2.length); // 6

It is generally recommended to avoid using sparse arrays.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK