feat(benchmark): add a simple benchmark for the di module

This commit is contained in:
vsavkin 2014-10-08 16:15:38 -04:00
parent 035dc5ba44
commit 1f4caa8773
12 changed files with 298 additions and 28 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
# Dont commit the following directories created by pub.
build/
benchpress-build/
packages/
.buildlog
node_modules

View File

@ -15,15 +15,24 @@ var fs = require('fs');
var path = require('path');
var readline = require('readline');
var Q = require('q');
var merge = require('merge');
var benchpress = require('angular-benchpress/lib/cli');
var js2es5Options = {
annotations: true, // parse annotations
types: true, // parse types
script: false, // parse as a module
modules: 'register',
modules: 'instantiate'
};
var js2es5OptionsProd = merge(true, js2es5Options, {
typeAssertions: false
});
var js2es5OptionsDev = merge(true, js2es5Options, {
typeAssertionModule: 'rtts_assert/rtts_assert',
typeAssertions: true
};
});
var js2dartOptions = {
annotations: true, // parse annotations
@ -38,8 +47,11 @@ var gulpTraceur = require('./tools/transpiler/gulp-traceur');
// traceur runtime
gulp.task('jsRuntime/build', function() {
var traceurRuntime = gulp.src(gulpTraceur.RUNTIME_PATH)
.pipe(gulp.dest('build/js'));
var traceurRuntime = gulp.src([
gulpTraceur.RUNTIME_PATH,
"node_modules/es6-module-loader/dist/es6-module-loader-sans-promises.src.js",
"node_modules/systemjs/lib/extension-register.js"
]).pipe(gulp.dest('build/js'));
return traceurRuntime;
});
@ -47,7 +59,6 @@ gulp.task('jsRuntime/build', function() {
// modules
var sourceTypeConfigs = {
dart: {
compilerOptions: js2dartOptions,
transpileSrc: ['modules/**/*.js'],
htmlSrc: ['modules/*/src/**/*.html'],
copySrc: ['modules/**/*.dart'],
@ -56,7 +67,6 @@ var sourceTypeConfigs = {
mimeType: 'application/dart'
},
js: {
compilerOptions: js2es5Options,
transpileSrc: ['modules/**/*.js', 'modules/**/*.es6'],
htmlSrc: ['modules/*/src/**/*.html'],
copySrc: ['modules/**/*.es5'],
@ -72,7 +82,7 @@ gulp.task('modules/clean', function() {
});
gulp.task('modules/build.dart/src', function() {
return createModuleTask(sourceTypeConfigs.dart);
return createModuleTask(merge(sourceTypeConfigs.dart, {compilerOptions: js2dartOptions}));
});
gulp.task('modules/build.dart/pubspec', function(done) {
@ -105,14 +115,24 @@ gulp.task('modules/build.dart/pubspec', function(done) {
gulp.task('modules/build.dart', ['modules/build.dart/src', 'modules/build.dart/pubspec']);
gulp.task('modules/build.js', function() {
return createModuleTask(sourceTypeConfigs.js);
gulp.task('modules/build.dev.js', function() {
return createModuleTask(merge(true, sourceTypeConfigs.js, {compilerOptions: js2es5OptionsDev}));
});
gulp.task('modules/build.prod.js', function() {
return createModuleTask(merge(true, sourceTypeConfigs.js, {compilerOptions: js2es5OptionsProd}));
});
function renameSrcToLib(file) {
file.dirname = file.dirname.replace(/\bsrc\b/, 'lib');
}
function renameEs5ToJs(file) {
if (file.extname == '.es5') {
file.extname = '.js';
}
}
function createModuleTask(sourceTypeConfig) {
var transpile = gulp.src(sourceTypeConfig.transpileSrc)
.pipe(rename({extname: '.'+sourceTypeConfig.outputExt}))
@ -121,6 +141,7 @@ function createModuleTask(sourceTypeConfig) {
.pipe(gulp.dest(sourceTypeConfig.outputDir));
var copy = gulp.src(sourceTypeConfig.copySrc)
.pipe(rename(renameSrcToLib))
.pipe(rename(renameEs5ToJs))
.pipe(gulp.dest(sourceTypeConfig.outputDir));
// TODO: provide the list of files to the template
// automatically!
@ -202,9 +223,34 @@ gulp.task('analyze/dartanalyzer', function(done) {
});
// ------------------
// BENCHMARKS
var benchmarksBuildPath = 'build/benchpress';
var benchmarksCompiledJsPath = 'build/js/benchmarks/lib';
gulp.task('benchmarks/build.benchpress', function () {
benchpress.build({
benchmarksPath: benchmarksCompiledJsPath,
buildPath: benchmarksBuildPath
})
});
gulp.task('benchmarks/build', function() {
runSequence(
['jsRuntime/build', 'modules/build.prod.js'],
'benchmarks/build.benchpress'
);
});
// ------------------
// WEB SERVER
gulp.task('serve', connect.server({
gulp.task('serve', function() {
connect.server({
root: [__dirname+'/build'],
port: 8000,
livereload: false,
@ -217,7 +263,10 @@ gulp.task('serve', connect.server({
next();
}];
}
}));
})();
});
// --------------
// general targets
@ -227,7 +276,7 @@ gulp.task('clean', ['modules/clean']);
gulp.task('build', function(done) {
runSequence(
// parallel
['jsRuntime/build', 'modules/build.dart', 'modules/build.js'],
['jsRuntime/build', 'modules/build.dart', 'modules/build.dev.js'],
// sequential
'analyze/dartanalyzer'
);

View File

@ -0,0 +1,15 @@
System.import('benchmarks/di/injector_get_benchmark').then(function (bm) {
window.benchmarkSteps.push({name: 'Injector.get (token)', fn: bm.run});
}, console.log.bind(console));
System.import('benchmarks/di/injector_get_by_key_benchmark').then(function (bm) {
window.benchmarkSteps.push({name: 'Injector.get (key)', fn: bm.run});
}, console.log.bind(console));
System.import('benchmarks/di/injector_get_child_benchmark').then(function (bm) {
window.benchmarkSteps.push({name: 'Injector.get (grand x 5 child)', fn: bm.run});
}, console.log.bind(console));
System.import('benchmarks/di/injector_instantiate_benchmark').then(function (bm) {
window.benchmarkSteps.push({name: 'Injector.instantiate', fn: bm.run});
}, console.log.bind(console));

View File

@ -0,0 +1,11 @@
module.exports = function(config) {
config.set({
scripts: [
{src: '/js/traceur-runtime.js'},
{src: '/js/es6-module-loader-sans-promises.src.js'},
{src: '/js/extension-register.js'},
{src: 'register_system.js'},
{src: 'benchmark.js'}
]
});
};

View File

@ -0,0 +1,43 @@
import {Injector} from "di/di";
var count = 0;
export function run () {
var bindings = [A, B, C, D, E];
var injector = new Injector(bindings);
for (var i = 0; i < 20000; ++i) {
injector.get(D);
injector.get(E);
}
}
class A {
constructor() {
count++;
}
}
class B {
constructor(a:A) {
count++;
}
}
class C {
constructor(b:B) {
count++;
}
}
class D {
constructor(c:C, b:B) {
count++;
}
}
class E {
constructor(d:D, c:C) {
count++;
}
}

View File

@ -0,0 +1,46 @@
import {Injector, Key} from "di/di";
var count = 0;
export function run () {
var bindings = [A, B, C, D, E];
var injector = new Injector(bindings);
var D_KEY = Key.get(D);
var E_KEY = Key.get(E);
for (var i = 0; i < 20000; ++i) {
injector.get(D_KEY);
injector.get(E_KEY);
}
}
class A {
constructor() {
count++;
}
}
class B {
constructor(a:A) {
count++;
}
}
class C {
constructor(b:B) {
count++;
}
}
class D {
constructor(c:C, b:B) {
count++;
}
}
class E {
constructor(d:D, c:C) {
count++;
}
}

View File

@ -0,0 +1,49 @@
import {Injector, Key} from "di/di";
var count = 0;
export function run () {
var bindings = [A, B, C, D, E];
var injector = new Injector(bindings);
var childInjector = injector.
createChild([]).
createChild([]).
createChild([]).
createChild([]).
createChild([]);
for (var i = 0; i < 20000; ++i) {
childInjector.get(D);
childInjector.get(E);
}
}
class A {
constructor() {
count++;
}
}
class B {
constructor(a:A) {
count++;
}
}
class C {
constructor(b:B) {
count++;
}
}
class D {
constructor(c:C, b:B) {
count++;
}
}
class E {
constructor(d:D, c:C) {
count++;
}
}

View File

@ -0,0 +1,45 @@
import {Injector, Key} from "di/di";
var count = 0;
export function run () {
var bindings = [A, B, C, D];
var injector = new Injector(bindings);
for (var i = 0; i < 1000; ++i) {
var child = injector.createChild([E]);
child.get(E);
}
console.log(count)
}
class A {
constructor() {
count++;
}
}
class B {
constructor(a:A) {
count++;
}
}
class C {
constructor(b:B) {
count++;
}
}
class D {
constructor(c:C, b:B) {
count++;
}
}
class E {
constructor(d:D, c:C) {
count++;
}
}

View File

View File

@ -0,0 +1,10 @@
System.paths = {
'core/*': '/js/core/lib/*.js',
'change_detection/*': '/js/change_detection/lib/*.js',
'facade/*': '/js/facade/lib/*.js',
'di/*': '/js/di/lib/*.js',
'rtts_assert/*': '/js/rtts_assert/lib/*.js',
'test_lib/*': '/js/test_lib/lib/*.js',
'benchmarks/*': '/js/benchmarks/lib/*.js'
};
register(System);

View File

@ -1,5 +1,5 @@
import {MapWrapper} from 'facade/collection';
import {FIELD, int} from 'facade/lang';
import {FIELD, int, isPresent} from 'facade/lang';
var _allKeys = {};
var _id:int = 0;
@ -15,9 +15,8 @@ export class Key {
static get(token) {
if (token instanceof Key) return token;
if (MapWrapper.contains(_allKeys, token)) {
return MapWrapper.get(_allKeys, token)
}
var obj = MapWrapper.get(_allKeys, token);
if (isPresent(obj)) return obj;
var newKey = new Key(token, ++_id);
MapWrapper.set(_allKeys, token, newKey);

View File

@ -10,6 +10,7 @@
"dependencies": {
"es6-module-loader": "^0.9.2",
"systemjs": "^0.9.1",
"angular-benchpress": "^0.1.3",
"gulp": "^3.8.8",
"gulp-rename": "^1.2.0",
"gulp-watch": "^1.0.3",
@ -18,6 +19,7 @@
"karma-chrome-launcher": "^0.1.4",
"karma-dart": "^0.2.8",
"karma-jasmine": "^0.2.2",
"merge": "^1.2.0",
"q": "^1.0.1",
"through2": "^0.6.1",
"event-stream": "^3.1.5",