Skip to content

Commit

Permalink
benchmark npm packages directly (#271)
Browse files Browse the repository at this point in the history
* benchmark npm packages directly

* Added commander to dev dependencies

* add three.js [skip ci]
  • Loading branch information
hzoo authored Nov 14, 2016
2 parents 73cfd55 + 7ad45c8 commit 33fffc3
Show file tree
Hide file tree
Showing 9 changed files with 148 additions and 74,155 deletions.
4 changes: 3 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ $ npm run fix
To run current benchmarks on a file:

```sh
$ ./scripts/benchmark.js file.js
$ ./scripts/benchmark.js package [file.js]
# do not remove package after installing to node_modules
$ ./scripts/benchmark.js package [file.js] --offline
```

To run current plugin timing on a file:
Expand Down
19 changes: 9 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,11 @@ Add to your `.babelrc`'s plugins array.

## Benchmarks
> Bootstrap: `npm run bootstrap`
> Build: `npm run build`
> Build: `npm run build`
> Running the benchmarks: `./scripts/benchmark.js <package>[@version] [relative-path/file.js]` - defaults to the package's main file if no file provided.
> Running the benchmarks: `./scripts/benchmark.js file.js`
Backbone.js:
Backbone.js v1.2.3:
```
raw raw win gzip gzip win parse time run
babili 21.72kB 222% 7.27kB 170% 2ms 859ms
Expand All @@ -161,9 +160,9 @@ closure 21.67kB 223% 7.37kB 167% 2ms 1635ms
closure js 24.01kB 191% 8.04kB 144% 2ms 4189ms
```

Run with: `./scripts/benchmark.js ./scripts/fixtures/backbone.js`
Run with: `./scripts/benchmark.js backbone@1.2.3`

React:
React v0.14.3:
```
raw raw win gzip gzip win parse time run
closure 171.46kB 265% 52.97kB 168% 14ms 4131ms
Expand All @@ -172,9 +171,9 @@ babili 176.59kB 255% 53.23kB 166% 15ms 4641ms
closure js 173.95kB 260% 53.53kB 165% 11ms 13792ms
```

Run with: `./scripts/benchmark.js ./scripts/fixtures/react.js`
Run with: `./scripts/benchmark.js react@0.14.3 react/dist/react.js`

jQuery:
jQuery v1.11.3:
```
raw raw win gzip gzip win parse time run
uglify 94.27kB 218% 32.78kB 158% 11ms 1394ms
Expand All @@ -183,7 +182,7 @@ closure 94.23kB 218% 33.38kB 153% 12ms 3152ms
closure js 95.64kB 213% 33.78kB 150% 10ms 14145ms
```

Run with: `./scripts/benchmark.js ./scripts/fixtures/jquery.js`
Run with: `./scripts/benchmark.js jquery@1.11.3`

Three.js:
```
Expand All @@ -193,7 +192,7 @@ uglify 479.43kB 99% 122.72kB 60% 39ms 3557ms
closure js 480.78kB 98% 123.34kB 59% 41ms 75621ms
```

Run with: `./scripts/benchmark.js ./scripts/fixtures/three.js`
Run with: `./scripts/benchmark.js three@0.82.1 three/build/three.js`

## Browser support

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"chalk": "^1.1.3",
"cli-table": "^0.3.1",
"closure-compiler": "^0.2.12",
"commander": "^2.9.0",
"eslint": "~3.0.0",
"eslint-config-babel": "^1.0.0",
"google-closure-compiler-js": "^20160822.0.0",
Expand Down
191 changes: 135 additions & 56 deletions scripts/benchmark.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,28 @@ const babel = require("babel-core");
const zlib = require("zlib");
const fs = require("fs");
const path = require("path");
const Command = require("commander").Command;
const compile = require("google-closure-compiler-js").compile;

const filename = process.argv[2];
if (!filename) {
console.error("Error: No filename specified");
let packagename, filename;

const script = new Command("benchmark.js")
.option("-o, --offline", "Only install package if not present; package not removed after testing")
.usage("[options] <package> [file]")
.arguments("<package> [file]")
.action(function(pname, fname) {
packagename = pname;
filename = fname;
})
.parse(process.argv);

if (!packagename) {
console.error("Error: No package specified");
process.exit(1);
}

const pathToScripts = __dirname;

const table = new Table({
head: ["", "raw", "raw win", "gzip", "gzip win", "parse time", "run"],
chars: {
Expand All @@ -46,10 +60,44 @@ const table = new Table({
},
});

let results = [];
let results = [],
code,
gzippedCode;

function installPackage() {
const command = "npm install --prefix " + pathToScripts + " " + packagename;

try {
child.execSync(command);
}
catch (e) {
// Unecessary to print out error as the failure of the execSync will print it anyway
process.exit(1);
}
}

function uninstallPackage() {
const command = "npm uninstall --prefix " + pathToScripts + " " + packagename.split("@")[0];

try {
child.execSync(command);
}
catch (e) {
console.error("Error uninstalling package " + packagename + ": " + e);
process.exit(1);
}
}

const code = fs.readFileSync(filename, "utf8");
const gzippedCode = zlib.gzipSync(code);
function checkFile() {
// If filename has not been passed as an argument, attempt to resolve file from package.json
filename = filename ? path.join(pathToScripts, "node_modules", filename) : require.resolve(packagename.split("@")[0]);
console.log("file: " + path.basename(filename));

if (!filename || !pathExists(filename)) {
console.error("File not found. Exiting.");
process.exit(1);
}
}

function test(name, callback) {
console.log("testing", name);
Expand Down Expand Up @@ -78,62 +126,93 @@ function test(name, callback) {
});
}

test("babili", function (code) {
return babel.transform(code, {
sourceType: "script",
presets: [require("../packages/babel-preset-babili")],
comments: false,
}).code;
});
function testFile() {
code = fs.readFileSync(filename, "utf8");
gzippedCode = zlib.gzipSync(code);

test("closure", function (/*code*/) {
return child.execSync(
"java -jar " + path.join(__dirname, "gcc.jar") + " --env=CUSTOM --jscomp_off=* --js " + filename
).toString();
});
test("babili", function (code) {
return babel.transform(code, {
sourceType: "script",
presets: [require("../packages/babel-preset-babili")],
comments: false,
}).code;
});

test("closure js", function (code) {
const flags = {
jsCode: [{ src: code }],
env: "CUSTOM",
};
const out = compile(flags);
return out.compiledCode;
});
test("closure", function (/*code*/) {
return child.execSync(
"java -jar " + path.join(__dirname, "gcc.jar") +
" --language_in=ECMASCRIPT5 --env=CUSTOM --jscomp_off=* --js " + filename
).toString();
});

test("uglify", function (code) {
return uglify.minify(code, {
fromString: true,
}).code;
});
test("closure js", function (code) {
const flags = {
jsCode: [{ src: code }],
env: "CUSTOM",
};
const out = compile(flags);
return out.compiledCode;
});

results = results.sort(function (a, b) {
return a.gzip > b.gzip;
});
test("uglify", function (code) {
return uglify.minify(code, {
fromString: true,
}).code;
});
}

function processResults() {
results = results.sort(function (a, b) {
return a.gzip > b.gzip;
});

results.forEach(function (result, i) {
let row = [
chalk.bold(result.name),
bytes(result.raw),
Math.round(((code.length / result.raw) * 100) - 100) + "%",
bytes(result.gzip),
Math.round(((gzippedCode.length / result.gzip) * 100) - 100) + "%",
Math.round(result.parse) + "ms",
Math.round(result.run) + "ms",
];

let style = chalk.yellow;
if (i === 0) {
style = chalk.green;
}
if (i === results.length - 1) {
style = chalk.red;
}
row = row.map(function (item) {
return style(item);
});

table.push(row);
});

results.forEach(function (result, i) {
let row = [
chalk.bold(result.name),
bytes(result.raw),
Math.round(((code.length / result.raw) * 100) - 100) + "%",
bytes(result.gzip),
Math.round(((gzippedCode.length / result.gzip) * 100) - 100) + "%",
Math.round(result.parse) + "ms",
Math.round(result.run) + "ms",
];

let style = chalk.yellow;
if (i === 0) {
style = chalk.green;
console.log(table.toString());
}

function pathExists(path) {
try {
return fs.statSync(path);
}
if (i === results.length - 1) {
style = chalk.red;
catch (e) {
return false;
}
row = row.map(function (item) {
return style(item);
});
}

table.push(row);
});
const packagePath = path.join(pathToScripts, "node_modules", packagename);

console.log(table.toString());
if (!pathExists(packagePath) || !script.offline) {
installPackage();
}

checkFile();
testFile();
processResults();

if (!script.offline) {
uninstallPackage();
}
Loading

0 comments on commit 33fffc3

Please sign in to comment.