288 lines
10 KiB
JavaScript
288 lines
10 KiB
JavaScript
"use strict";
|
|
|
|
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /**
|
|
* Copyright (c) 2017-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*/
|
|
|
|
var _index = require("./serializer/index.js");
|
|
|
|
var _index2 = _interopRequireDefault(_index);
|
|
|
|
var _construct_realm = require("./construct_realm.js");
|
|
|
|
var _construct_realm2 = _interopRequireDefault(_construct_realm);
|
|
|
|
var _globals = require("./globals.js");
|
|
|
|
var _globals2 = _interopRequireDefault(_globals);
|
|
|
|
var _invariant = require("./invariant.js");
|
|
|
|
var _invariant2 = _interopRequireDefault(_invariant);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var chalk = require("chalk");
|
|
var jsdom = require("jsdom");
|
|
var zlib = require("zlib");
|
|
var fs = require("fs");
|
|
var vm = require("vm");
|
|
|
|
function getTime() {
|
|
var stamp = process.hrtime();
|
|
return (stamp[0] * 1e9 + stamp[1]) / 1e6;
|
|
}
|
|
|
|
function exec(code, compatibility) {
|
|
var sandbox = {
|
|
setTimeout: setTimeout,
|
|
setInterval: setInterval,
|
|
console: {
|
|
error: function error() {},
|
|
log: function log(s) {
|
|
console.log(s);
|
|
}
|
|
}
|
|
};
|
|
|
|
var beforeCode = "var global = this; ";
|
|
var afterCode = "// At the end of the script, Node tries to clone the 'this' Object (global) which involves executing all getters on it.\n// To avoid executing any more code (which could affect timing), we just set all globals to undefined (hoping that doesn't take too long).\nObject.getOwnPropertyNames(global).forEach(function(name){ if (name !== \"Object\" && name !== \"global\") global[name] = undefined; });";
|
|
|
|
if (compatibility === "browser") {
|
|
beforeCode += "var window = this; var self = this; ";
|
|
var window = jsdom.jsdom({}).defaultView;
|
|
sandbox.window = window;
|
|
sandbox.document = window.document;
|
|
sandbox.navigator = window.navigator;
|
|
sandbox.location = window.location;
|
|
}
|
|
if (compatibility === "jsc-600-1-4-17") {
|
|
beforeCode += "delete global.clearInterval; delete global.clearImmediate; delete global.clearTimeout; delete global.setImmediate; delete Object.assign;";
|
|
}
|
|
|
|
code = beforeCode + " " + code + "; // keep newline here as code may end with comment\n" + afterCode;
|
|
|
|
var start = getTime();
|
|
var script = new vm.Script(code, { cachedDataProduced: false });
|
|
var executedStart = getTime();
|
|
script.runInNewContext(sandbox);
|
|
var executedEnd = getTime();
|
|
|
|
return {
|
|
raw: code.length,
|
|
gzip: zlib.gzipSync(code).length,
|
|
executed: executedEnd - executedStart,
|
|
compiled: executedStart - start,
|
|
total: executedEnd - start
|
|
};
|
|
}
|
|
|
|
function line(type, code, compatibility) {
|
|
var moreOut = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
var compareStats = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : undefined;
|
|
|
|
var stats = exec(code, compatibility);
|
|
|
|
function wrapTime(key) {
|
|
return wrap(key, function (ms) {
|
|
return ms.toFixed(2) + "ms";
|
|
}, "faster", "slower");
|
|
}
|
|
|
|
function wrapSize(key) {
|
|
return wrap(key, function (b) {
|
|
var kilobytes = Math.round(b / 1000);
|
|
if (kilobytes > 1000) {
|
|
return (kilobytes / 1000).toFixed(2) + "MB";
|
|
} else {
|
|
return kilobytes + "KB";
|
|
}
|
|
}, "smaller", "bigger");
|
|
}
|
|
|
|
function wrap(key, format, positive, negative) {
|
|
if (compareStats) {
|
|
var before = compareStats[key];
|
|
var after = stats[key];
|
|
var factor = void 0;
|
|
|
|
if (after < before) {
|
|
factor = chalk.green((before / after).toFixed(2) + "x " + positive);
|
|
} else {
|
|
factor = chalk.red((after / before).toFixed(2) + "x " + negative);
|
|
}
|
|
|
|
return format(after) + " " + factor;
|
|
} else {
|
|
return format(stats[key]);
|
|
}
|
|
}
|
|
|
|
var out = _extends({
|
|
"VM Total Time": wrapTime("total"),
|
|
"VM Compile Time": wrapTime("compiled"),
|
|
"VM Execution Time": wrapTime("executed"),
|
|
"Raw Code Size": wrapSize("raw"),
|
|
"Gzip Code Size": wrapSize("gzip")
|
|
}, moreOut);
|
|
|
|
console.log(chalk.bold(type));
|
|
|
|
for (var key in out) {
|
|
console.log(" " + chalk.bold(key) + " " + out[key]);
|
|
}
|
|
|
|
return stats;
|
|
}
|
|
|
|
function dump(name, raw) {
|
|
var min = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : raw;
|
|
var compatibility = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : "browser";
|
|
var outputFilename = arguments[4];
|
|
|
|
console.log(chalk.inverse(name));
|
|
var beforeStats = line("Before", min, compatibility);
|
|
|
|
var start = Date.now();
|
|
var realm = (0, _construct_realm2.default)({ serialize: true, compatibility: compatibility });
|
|
(0, _globals2.default)(realm);
|
|
var serializer = new _index2.default(realm);
|
|
var sources = [{ filePath: name, fileContents: raw }];
|
|
var serialized = serializer.init(sources);
|
|
if (!serialized) {
|
|
process.exit(1);
|
|
(0, _invariant2.default)(false);
|
|
}
|
|
var code = serialized.code;
|
|
var total = Date.now() - start;
|
|
|
|
if (code.length >= 1000 || outputFilename) {
|
|
var filename = outputFilename || name + "-processed.js";
|
|
console.log("Prepacked source code written to " + filename + ".");
|
|
fs.writeFileSync(filename, code);
|
|
}
|
|
|
|
line("After", code, compatibility, {
|
|
"Prepack Compile Time": total + "ms"
|
|
}, beforeStats);
|
|
|
|
if (code.length <= 1000 && !outputFilename) {
|
|
console.log("+++++++++++++++++ Prepacked source code");
|
|
console.log(code);
|
|
console.log("=================");
|
|
}
|
|
}
|
|
|
|
var args = Array.from(process.argv);
|
|
args.splice(0, 2);
|
|
var inputFilename = void 0;
|
|
var outputFilename = void 0;
|
|
var compatibility = void 0;
|
|
while (args.length) {
|
|
var arg = args[0];
|
|
args.shift();
|
|
if (arg === "--out") {
|
|
arg = args[0];
|
|
args.shift();
|
|
outputFilename = arg;
|
|
} else if (arg === "--compatibility") {
|
|
arg = args[0];
|
|
args.shift();
|
|
if (arg !== "jsc-600-1-4-17") {
|
|
console.error("Unsupported compatibility: " + arg);
|
|
process.exit(1);
|
|
} else {
|
|
compatibility = arg;
|
|
}
|
|
} else if (arg === "--help") {
|
|
console.log("Usage: benchmarker.js [ --out output.js ] [ --compatibility jsc ] [ -- | input.js ]");
|
|
} else if (!arg.startsWith("--")) {
|
|
inputFilename = arg;
|
|
} else {
|
|
console.error("Unknown option: " + arg);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
if (!inputFilename) {
|
|
console.error("Missing input file.");
|
|
process.exit(1);
|
|
} else {
|
|
var input = fs.readFileSync(inputFilename, "utf8");
|
|
dump(inputFilename, input, input, compatibility, outputFilename);
|
|
}
|
|
|
|
//dump("helloWorld", "function hello() { return 'hello'; } function world() { return 'world'; } s = hello() + ' ' + world();");
|
|
|
|
//dump("regex", "regex = /Facebook/i;");
|
|
|
|
//dump("test", "try { new WeakSet().delete.call(0, {}); } catch (e) {console.log(e);}");
|
|
//dump("test", "e = 'abcdef'.substr(1,2); ");
|
|
//dump("test", "var s = 'Promise'; e = s[0];");
|
|
//dump("test", "foo = function() { return [,0]; };");
|
|
|
|
//dump("simple", "var foo = 5 * 5; var bar = [2, 3, 'yes']; var foo2 = null; var bar2 = undefined;");
|
|
//dump("simple2", "function Foo() {} Foo.prototype.wow = function () {};");
|
|
|
|
//dump("Date.now", "Date.now");
|
|
//dump("Date.now", "this.foo = Date.now();");
|
|
//dump("object recursion", "var obj = { yes: 'no' }; obj.bar = obj; var foo = [obj]; obj.foobar = foo;");
|
|
//dump("intrinsic union", "var assign = Object.assign || function () {}; var obj = assign({ foo: 1 }, { bar: 2 });");
|
|
|
|
/*dump(
|
|
"fbsdk",
|
|
fs.readFileSync(__dirname + "/../assets/fbsdk.js", "utf8")
|
|
);*/
|
|
|
|
/*dump(
|
|
"react",
|
|
fs.readFileSync(__dirname + "/../assets/react.js", "utf8"),
|
|
fs.readFileSync(__dirname + "/../assets/react.min.js", "utf8")
|
|
);*/
|
|
|
|
/*dump(
|
|
"immutable",
|
|
fs.readFileSync(__dirname + "/../assets/immutable.js", "utf8"),
|
|
fs.readFileSync(__dirname + "/../assets/immutable.min.js", "utf8")
|
|
);*/
|
|
|
|
/*dump(
|
|
"react-native-bundle",
|
|
fs.readFileSync(__dirname + "/../../examples/react-native-bundle/bundle.js", "utf8")
|
|
);*/
|
|
|
|
/*dump(
|
|
"lodash",
|
|
fs.readFileSync(require.resolve("lodash/lodash.js"), "utf8"),
|
|
fs.readFileSync(require.resolve("lodash/lodash.min.js"), "utf8")
|
|
);*/
|
|
|
|
/*dump(
|
|
"underscore",
|
|
fs.readFileSync(require.resolve("underscore"), "utf8"),
|
|
fs.readFileSync(require.resolve("underscore/underscore-min"), "utf8")
|
|
);
|
|
*/
|
|
|
|
/*dump(
|
|
"ember",
|
|
fs.readFileSync("ember.prod.js", "utf8")
|
|
);
|
|
|
|
dump(
|
|
"jquery",
|
|
fs.readFileSync(require.resolve("jquery/dist/jquery.js"), "utf8"),
|
|
fs.readFileSync(require.resolve("jquery/dist/jquery.min.js"), "utf8")
|
|
);
|
|
|
|
dump(
|
|
"scrollin",
|
|
fs.readFileSync("scrollin.js", "utf8")
|
|
);
|
|
*/
|
|
//# sourceMappingURL=benchmarker.js.map
|