├── dist
└── tags
│ └── tags.json
├── .jshintrc
├── .npmignore
├── gulpfile.js
├── jsconfig.json
├── app
├── benchmark-resources
│ ├── content-selectors.js
│ ├── point.html
│ ├── surrogate-behaviors.html
│ ├── point.js
│ ├── template-parts.html
│ ├── template-parts.js
│ ├── content-selectors.html
│ ├── index.js
│ ├── surrogate-behaviors.js
│ └── attributes.js
├── benchmarking
│ ├── type.js
│ ├── definition.js
│ ├── result-factory.js
│ ├── definition-repository.js
│ ├── macro-runner.js
│ ├── coordinator.js
│ ├── micro-runner.js
│ └── result-repository.js
├── resources
│ ├── skip-value-converter.js
│ ├── take-value-converter.js
│ └── index.js
├── util
│ ├── user-agent.js
│ └── parse-json.js
├── ui
│ ├── harness
│ │ ├── result-set.html
│ │ ├── result-set.js
│ │ ├── harness.js
│ │ └── harness.html
│ ├── app.html
│ ├── app.js
│ ├── tags
│ │ ├── chart.js
│ │ ├── tags.html
│ │ └── tags.js
│ └── benchmark-view-model.js
├── styles.css
├── index.html
└── main.js
├── .gitignore
├── benchmarks
├── micro
│ ├── templating-compile-vanilla
│ │ └── index.js
│ ├── templating-create-vanilla
│ │ └── index.js
│ ├── di-singleton
│ │ └── index.js
│ ├── di-transient
│ │ └── index.js
│ ├── templating-compile-and-create-vanilla
│ │ └── index.js
│ ├── templating-create-with-bindings
│ │ └── index.js
│ ├── templating-compile-and-create-with-bindings
│ │ └── index.js
│ ├── templating-compile-template-parts
│ │ └── index.js
│ ├── templating-compile-with-behaviors
│ │ └── index.js
│ ├── templating-compile-with-bindings
│ │ └── index.js
│ ├── templating-create-template-parts
│ │ └── index.js
│ ├── templating-create-with-behaviors
│ │ └── index.js
│ ├── di-singleton-parent
│ │ └── index.js
│ ├── di-singleton-parent4
│ │ └── index.js
│ ├── di-transient-parent
│ │ └── index.js
│ ├── di-transient-parent4
│ │ └── index.js
│ ├── templating-compile-and-create-template-parts
│ │ └── index.js
│ ├── templating-compile-and-create-with-behaviors
│ │ └── index.js
│ ├── templating-compile-content-selectors
│ │ └── index.js
│ ├── templating-create-content-selectors
│ │ └── index.js
│ ├── di-auto-registration-sans-metadata
│ │ └── index.js
│ ├── templating-compile-and-create-content-selectors
│ │ └── index.js
│ ├── di-instance
│ │ └── index.js
│ ├── templating-compile-surrogate-behaviors
│ │ └── index.js
│ ├── templating-create-surrogate-behaviors
│ │ └── index.js
│ ├── di-auto-registration-with-metadata
│ │ └── index.js
│ ├── templating-compile-with-bindings-and-behaviors
│ │ └── index.js
│ ├── templating-create-with-bindings-and-behaviors
│ │ └── index.js
│ ├── templating-compile-and-create-with-bindings-and-behaviors
│ │ └── index.js
│ ├── di-instance-parent
│ │ └── index.js
│ ├── di-instance-parent4
│ │ └── index.js
│ ├── di-create-child-container
│ │ └── index.js
│ ├── binding-parse-simple
│ │ └── index.js
│ ├── binding-parse-cached
│ │ └── index.js
│ ├── binding-parse-complex
│ │ └── index.js
│ ├── binding-interpolation-short
│ │ └── index.js
│ ├── container.js
│ ├── binding-bind
│ │ └── index.js
│ ├── binding-bind-interpolation
│ │ └── index.js
│ ├── binding-observer-locator
│ │ └── index.js
│ ├── binding-interpolation-long
│ │ └── index.js
│ └── templating.js
└── macro
│ ├── simple-form
│ ├── app.js
│ ├── index.html
│ ├── main.js
│ └── app.html
│ └── simple-table
│ ├── index.html
│ ├── main.js
│ ├── app.html
│ └── app.js
├── server
├── controllers
│ ├── static.js
│ ├── tests.js
│ └── tags.js
├── main.js
└── fsutil
│ └── directory.js
├── .editorconfig
├── CONTRIBUTING.md
├── LICENSE
├── benchmark-plan.md
├── ISSUE_TEMPLATE.md
├── package.json
├── optimization-plan.md
├── README.md
└── config.js
/dist/tags/tags.json:
--------------------------------------------------------------------------------
1 | []
2 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "esnext": true
3 | }
4 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | jspm_packages
2 | bower_components
3 | .idea
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | require('require-dir')('build/tasks');
2 |
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES6"
4 | }
5 | }
--------------------------------------------------------------------------------
/app/benchmark-resources/content-selectors.js:
--------------------------------------------------------------------------------
1 | export class ContentSelectors {
2 | }
3 |
--------------------------------------------------------------------------------
/app/benchmarking/type.js:
--------------------------------------------------------------------------------
1 | export var type = {
2 | micro: 'micro',
3 | macro: 'macro'
4 | }
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | jspm_packages
3 | bower_components
4 | /dist
5 | .idea
6 | .DS_STORE
7 |
--------------------------------------------------------------------------------
/app/benchmark-resources/point.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Hello, I'm a point. Here's where I am: (${x}, ${y})
4 |
5 |
--------------------------------------------------------------------------------
/app/resources/skip-value-converter.js:
--------------------------------------------------------------------------------
1 | export class SkipValueConverter {
2 | toView(array, count) {
3 | return array.slice(count);
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/app/benchmarking/definition.js:
--------------------------------------------------------------------------------
1 | export class Definition {
2 | constructor(name, type) {
3 | this.name = name;
4 | this.type = type;
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/app/resources/take-value-converter.js:
--------------------------------------------------------------------------------
1 | export class TakeValueConverter {
2 | toView(array, count) {
3 | return array.slice(0, count);
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/app/benchmark-resources/surrogate-behaviors.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | surrogate behaviors
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/resources/index.js:
--------------------------------------------------------------------------------
1 | export function configure(framework) {
2 | framework.globalResources(
3 | './skip-value-converter',
4 | './take-value-converter'
5 | );
6 | }
7 |
--------------------------------------------------------------------------------
/benchmarks/micro/templating-compile-vanilla/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark, template} from '../templating';
2 |
3 | export default createBenchmark('ViewCompiler', template.vanilla);
4 |
--------------------------------------------------------------------------------
/benchmarks/micro/templating-create-vanilla/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark, template} from '../templating';
2 |
3 | export default createBenchmark('ViewFactory', template.vanilla);
4 |
--------------------------------------------------------------------------------
/app/benchmark-resources/point.js:
--------------------------------------------------------------------------------
1 | import {customElement, bindable} from 'aurelia-framework';
2 |
3 | @customElement('point')
4 | export class Point {
5 | @bindable x;
6 | @bindable y;
7 | }
--------------------------------------------------------------------------------
/app/benchmark-resources/template-parts.html:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/benchmarks/micro/di-singleton/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark} from '../container';
2 |
3 | export default createBenchmark(
4 | (container, ctor) => container.registerSingleton(ctor));
5 |
--------------------------------------------------------------------------------
/benchmarks/micro/di-transient/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark} from '../container';
2 |
3 | export default createBenchmark(
4 | (container, ctor) => container.registerTransient(ctor));
5 |
--------------------------------------------------------------------------------
/benchmarks/micro/templating-compile-and-create-vanilla/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark, template} from '../templating';
2 |
3 | export default createBenchmark('Both', template.vanilla);
4 |
--------------------------------------------------------------------------------
/benchmarks/micro/templating-create-with-bindings/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark, template} from '../templating';
2 |
3 | export default createBenchmark('ViewFactory', template.bindingsOnly);
4 |
--------------------------------------------------------------------------------
/benchmarks/micro/templating-compile-and-create-with-bindings/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark, template} from '../templating';
2 |
3 | export default createBenchmark('Both', template.bindingsOnly);
4 |
--------------------------------------------------------------------------------
/benchmarks/micro/templating-compile-template-parts/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark, template} from '../templating';
2 |
3 | export default createBenchmark('ViewCompiler', template.templateParts);
4 |
--------------------------------------------------------------------------------
/benchmarks/micro/templating-compile-with-behaviors/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark, template} from '../templating';
2 |
3 | export default createBenchmark('ViewCompiler', template.behaviorsOnly);
4 |
--------------------------------------------------------------------------------
/benchmarks/micro/templating-compile-with-bindings/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark, template} from '../templating';
2 |
3 | export default createBenchmark('ViewCompiler', template.bindingsOnly);
4 |
--------------------------------------------------------------------------------
/benchmarks/micro/templating-create-template-parts/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark, template} from '../templating';
2 |
3 | export default createBenchmark('ViewFactory', template.templateParts);
4 |
--------------------------------------------------------------------------------
/benchmarks/micro/templating-create-with-behaviors/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark, template} from '../templating';
2 |
3 | export default createBenchmark('ViewFactory', template.behaviorsOnly);
4 |
--------------------------------------------------------------------------------
/app/benchmark-resources/template-parts.js:
--------------------------------------------------------------------------------
1 | import {customElement, bindable} from 'aurelia-framework';
2 |
3 | @customElement('template-parts')
4 | export class TemplateParts {
5 | @bindable items;
6 | }
7 |
--------------------------------------------------------------------------------
/benchmarks/micro/di-singleton-parent/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark} from '../container';
2 |
3 | export default createBenchmark(
4 | (container, ctor) => container.registerSingleton(ctor), 0, 1);
5 |
--------------------------------------------------------------------------------
/benchmarks/micro/di-singleton-parent4/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark} from '../container';
2 |
3 | export default createBenchmark(
4 | (container, ctor) => container.registerSingleton(ctor), 2, 6);
5 |
--------------------------------------------------------------------------------
/benchmarks/micro/di-transient-parent/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark} from '../container';
2 |
3 | export default createBenchmark(
4 | (container, ctor) => container.registerTransient(ctor), 2, 6);
5 |
--------------------------------------------------------------------------------
/benchmarks/micro/di-transient-parent4/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark} from '../container';
2 |
3 | export default createBenchmark(
4 | (container, ctor) => container.registerTransient(ctor), 2, 6);
5 |
--------------------------------------------------------------------------------
/benchmarks/micro/templating-compile-and-create-template-parts/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark, template} from '../templating';
2 |
3 | export default createBenchmark('Both', template.templateParts);
4 |
--------------------------------------------------------------------------------
/benchmarks/micro/templating-compile-and-create-with-behaviors/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark, template} from '../templating';
2 |
3 | export default createBenchmark('Both', template.behaviorsOnly);
4 |
--------------------------------------------------------------------------------
/benchmarks/micro/templating-compile-content-selectors/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark, template} from '../templating';
2 |
3 | export default createBenchmark('ViewCompiler', template.contentSelectors);
4 |
--------------------------------------------------------------------------------
/benchmarks/micro/templating-create-content-selectors/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark, template} from '../templating';
2 |
3 | export default createBenchmark('ViewFactory', template.contentSelectors);
4 |
--------------------------------------------------------------------------------
/benchmarks/micro/di-auto-registration-sans-metadata/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark} from '../container';
2 |
3 | export default createBenchmark(
4 | (container, ctor) => container.autoRegister(ctor));
5 |
--------------------------------------------------------------------------------
/benchmarks/micro/templating-compile-and-create-content-selectors/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark, template} from '../templating';
2 |
3 | export default createBenchmark('Both', template.contentSelectors);
4 |
--------------------------------------------------------------------------------
/benchmarks/micro/di-instance/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark} from '../container';
2 |
3 | export default createBenchmark(
4 | (container, ctor) => container.registerInstance(ctor, 'How much do you bench?'));
5 |
--------------------------------------------------------------------------------
/benchmarks/micro/templating-compile-surrogate-behaviors/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark, template} from '../templating';
2 |
3 | export default createBenchmark('ViewCompiler', template.compileSurrogateBehaviors);
4 |
--------------------------------------------------------------------------------
/benchmarks/micro/templating-create-surrogate-behaviors/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark, template} from '../templating';
2 |
3 | export default createBenchmark('ViewFactory', template.createSurrogateBehaviors);
4 |
--------------------------------------------------------------------------------
/benchmarks/micro/di-auto-registration-with-metadata/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark} from '../container';
2 |
3 | export default createBenchmark(
4 | (container, ctor) => container.autoRegister(ctor), 0, 0, true);
5 |
--------------------------------------------------------------------------------
/benchmarks/micro/templating-compile-with-bindings-and-behaviors/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark, template} from '../templating';
2 |
3 | export default createBenchmark('ViewCompiler', template.bindingsAndBehaviors);
4 |
--------------------------------------------------------------------------------
/benchmarks/micro/templating-create-with-bindings-and-behaviors/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark, template} from '../templating';
2 |
3 | export default createBenchmark('ViewFactory', template.bindingsAndBehaviors);
4 |
--------------------------------------------------------------------------------
/benchmarks/micro/templating-compile-and-create-with-bindings-and-behaviors/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark, template} from '../templating';
2 |
3 | export default createBenchmark('Both', template.bindingsAndBehaviors);
4 |
--------------------------------------------------------------------------------
/benchmarks/micro/di-instance-parent/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark} from '../container';
2 |
3 | export default createBenchmark(
4 | (container, ctor) => container.registerInstance(ctor, 'How much do you bench?'), 0, 1);
5 |
--------------------------------------------------------------------------------
/benchmarks/micro/di-instance-parent4/index.js:
--------------------------------------------------------------------------------
1 | import {createBenchmark} from '../container';
2 |
3 | export default createBenchmark(
4 | (container, ctor) => container.registerInstance(ctor, 'How much do you bench?'), 0, 1);
5 |
--------------------------------------------------------------------------------
/app/benchmark-resources/content-selectors.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/benchmark-resources/index.js:
--------------------------------------------------------------------------------
1 | export function configure(config) {
2 | config.globalResources(
3 | './attributes',
4 | './point',
5 | './content-selectors',
6 | './template-parts',
7 | './surrogate-behaviors');
8 | }
9 |
--------------------------------------------------------------------------------
/benchmarks/macro/simple-form/app.js:
--------------------------------------------------------------------------------
1 | export class App {
2 | fromAirport = 'JFK';
3 | toAirport = 'LHR';
4 | departureDate = '7/29/2015';
5 | returnDate = '8/13/2015';
6 | passengers = 2;
7 | includeNearby = false;
8 | flexibleDates = true;
9 | }
10 |
--------------------------------------------------------------------------------
/app/benchmark-resources/surrogate-behaviors.js:
--------------------------------------------------------------------------------
1 | import {customElement} from 'aurelia-framework';
2 |
3 | @customElement('surrogate-behaviors')
4 | export class SurrogateBehaviors {
5 | foo = 'foo';
6 | bar = 'bar';
7 | baz = 'baz';
8 | world = 'world';
9 | }
10 |
--------------------------------------------------------------------------------
/app/util/user-agent.js:
--------------------------------------------------------------------------------
1 | import UAParser from 'faisalman/ua-parser-js/ua-parser.min.js';
2 |
3 | let parser = new UAParser(),
4 | browser = parser.getBrowser(), // {name, version}
5 | os = parser.getOS(); // {name, version}
6 |
7 | export var userAgent = `${browser.name} on ${os.name} ${os.version}`;
8 |
--------------------------------------------------------------------------------
/server/controllers/static.js:
--------------------------------------------------------------------------------
1 | var express = require("express");
2 | var router = express.Router();
3 |
4 | router.get("/", function(request, response) {
5 | response.redirect("/dist/app/index.html");
6 | });
7 |
8 | router.use(express.static(__dirname + "/../../"));
9 |
10 | module.exports = router;
11 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | end_of_line = lf
9 | insert_final_newline = true
10 |
11 | # 2 space indentation
12 | [**.*]
13 | indent_style = space
14 | indent_size = 2
15 |
--------------------------------------------------------------------------------
/benchmarks/macro/simple-form/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Simple Form
5 |
6 |
7 |
8 |
9 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/benchmarks/macro/simple-table/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Simple Form
5 |
6 |
7 |
8 |
9 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/benchmarks/micro/di-create-child-container/index.js:
--------------------------------------------------------------------------------
1 | import {Container} from 'aurelia-framework';
2 |
3 | export default deferred => {
4 | var container = new Container(), current, i = 100, j;
5 | while(i--) {
6 | current = container.createChild();
7 | j = 50;
8 | while(j--) {
9 | current = current.createChild();
10 | }
11 | }
12 | deferred.resolve();
13 | };
14 |
--------------------------------------------------------------------------------
/benchmarks/macro/simple-form/main.js:
--------------------------------------------------------------------------------
1 | document.addEventListener(
2 | "aurelia-composed",
3 | () => parent.postMessage("test-end", "*"), false);
4 |
5 | export function configure(aurelia) {
6 | console.log('start');
7 | parent.postMessage("test-start", "*");
8 | aurelia.use
9 | .standardConfiguration()
10 | .developmentLogging();
11 |
12 | aurelia.start().then(a => a.setRoot());
13 | }
14 |
--------------------------------------------------------------------------------
/benchmarks/macro/simple-table/main.js:
--------------------------------------------------------------------------------
1 | document.addEventListener(
2 | "aurelia-composed",
3 | () => parent.postMessage("test-end", "*"), false);
4 |
5 | export function configure(aurelia) {
6 | console.log('start');
7 | parent.postMessage("test-start", "*");
8 | aurelia.use
9 | .standardConfiguration()
10 | .developmentLogging();
11 |
12 | aurelia.start().then(a => a.setRoot());
13 | }
14 |
--------------------------------------------------------------------------------
/app/util/parse-json.js:
--------------------------------------------------------------------------------
1 | function dateReviver(name, value) {
2 | if (typeof value === 'string') {
3 | var a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
4 | if (a) {
5 | return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6]));
6 | }
7 | }
8 | return value;
9 | }
10 |
11 | export function parseJson(json) {
12 | return JSON.parse(json, dateReviver);
13 | }
14 |
--------------------------------------------------------------------------------
/server/main.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var bodyParser = require('body-parser');
3 | var app = express();
4 |
5 | app.use(bodyParser.json())
6 | app.use(require('./controllers/static.js'));
7 | app.use('/api/tests', require('./controllers/tests.js'));
8 | app.use('/api/tags', require('./controllers/tags.js'));
9 |
10 | var port = 8080;
11 | app.listen(port, function(){
12 | console.log('Server listening on', port);
13 | });
14 |
--------------------------------------------------------------------------------
/app/ui/harness/result-set.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | ${result.period.toFixed(4)}
4 | ${result.heapDelta}
6 | ${result.tag}
7 |
8 |
9 |
--------------------------------------------------------------------------------
/benchmarks/micro/binding-parse-simple/index.js:
--------------------------------------------------------------------------------
1 | import {Parser} from 'aurelia-framework';
2 |
3 | var expressions = [], i;
4 | for(i = 0; i < 100; i++) {
5 | expressions.push('memberAccessExpression' + i);
6 | }
7 |
8 | export default deferred => {
9 | var parser = new Parser(), expression;
10 | i = expressions.length;
11 | while(i--) {
12 | expression = expressions[i];
13 | parser.parse(expression);
14 | }
15 | deferred.resolve();
16 | };
17 |
--------------------------------------------------------------------------------
/benchmarks/macro/simple-table/app.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | | Planet |
6 | Diameter (miles) |
7 | Distance to Sun (miles) |
8 |
9 |
10 |
11 |
12 | | ${planet.name} |
13 | ${planet.diameter} |
14 | ${planet.distance} |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/server/controllers/tests.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var directory = require('../fsutil/directory');
3 | var router = express.Router();
4 |
5 | router.get('/', function(request, response) {
6 | var microTests = directory.getChildren('/benchmarks/micro');
7 | var macroTests = directory.getChildren('/benchmarks/macro');
8 |
9 | response.json({
10 | micro : microTests,
11 | macro: macroTests
12 | });
13 | });
14 |
15 | module.exports = router;
16 |
--------------------------------------------------------------------------------
/app/styles.css:
--------------------------------------------------------------------------------
1 | .host {
2 | margin-top: 4em;
3 | }
4 |
5 | .running-indicator {
6 | margin-top: 0.5em;
7 | }
8 |
9 | /**
10 | * harness view
11 | */
12 | .harness .tagged-result {
13 | font-weight: bold;
14 | }
15 |
16 | .harness .user-agent {
17 | display: inline-block;
18 | width: 15em;
19 | text-align: right;
20 | }
21 |
22 | .harness th > form {
23 | font-weight: normal;
24 | }
25 |
26 | .harness .tagged {
27 | font-weight: bold;
28 | }
29 |
30 | /**
31 | * results view
32 | */
33 |
--------------------------------------------------------------------------------
/app/benchmark-resources/attributes.js:
--------------------------------------------------------------------------------
1 | import {customAttribute, inject} from 'aurelia-framework';
2 |
3 | @inject(Element)
4 | class Attr {
5 | constructor(element) {
6 | this.element = element;
7 | }
8 |
9 | attached() {
10 | console.log(`attached to ${this.element.outerHTML}`);
11 | }
12 | }
13 |
14 | @customAttribute('foo')
15 | export class Foo extends Attr {}
16 |
17 | @customAttribute('bar')
18 | export class Bar extends Attr {}
19 |
20 | @customAttribute('baz')
21 | export class Baz extends Attr {}
--------------------------------------------------------------------------------
/benchmarks/micro/binding-parse-cached/index.js:
--------------------------------------------------------------------------------
1 | import {Parser} from 'aurelia-framework';
2 |
3 | var parser = new Parser(),
4 | simple = 'memberAccessExpresion',
5 | complex = 'some.complex.expression[that](is, really, complex).and.expensive[3].to.parse ? "and" : "long" | withAConverter:and:parameters';
6 | parser.parse(simple);
7 | parser.parse(complex);
8 |
9 | export default deferred => {
10 | var i = 100;
11 | while(i--) {
12 | parser.parse(simple);
13 | parser.parse(complex);
14 | }
15 | deferred.resolve();
16 | };
17 |
--------------------------------------------------------------------------------
/app/benchmarking/result-factory.js:
--------------------------------------------------------------------------------
1 | import {userAgent} from '../util/user-agent';
2 |
3 | export class ResultFactory {
4 | fromMeasures(name, measures) {
5 | let deltas = measures.heapDeltas.filter(x => x >= 0); // filter out drops due to GC
6 | let averageHeapDelta = deltas.length ? Math.floor(deltas.reduce((a, b) => a + b) / deltas.length) : 0;
7 | return {
8 | name: name,
9 | timestamp: new Date(),
10 | userAgent: userAgent,
11 | period: measures.period,
12 | heapDelta: averageHeapDelta,
13 | tag: ''
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/benchmarks/macro/simple-table/app.js:
--------------------------------------------------------------------------------
1 | export class App {
2 | planets = [
3 | { name: 'Mercury', diameter: 3032, distance: 35983610 },
4 | { name: 'Venus', diameter: 7521, distance: 67232360 },
5 | { name: 'Earth', diameter: 7926, distance: 92957100 },
6 | { name: 'Mars', diameter: 4222, distance: 141635300 },
7 | { name: 'Jupiter', diameter: 88846, distance: 483632000 },
8 | { name: 'Saturn', diameter: 74898, distance: 888188000 },
9 | { name: 'Uranus', diameter: 31763, distance: 1783950000 },
10 | { name: 'Neptune', diameter: 30778, distance: 2798842000 },
11 | ];
12 | }
13 |
--------------------------------------------------------------------------------
/benchmarks/macro/simple-form/app.html:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | We'd love for you to contribute and to make this project even better than it is today! If this interests you, please begin by reading [our contributing guidelines](https://github.com/DurandalProject/about/blob/master/CONTRIBUTING.md). The contributing document will provide you with all the information you need to get started. Once you have read that, you will need to also [sign our CLA](http://goo.gl/forms/dI8QDDSyKR) before we can accept a Pull Request from you. More information on the process is included in the [contributor's guide](https://github.com/DurandalProject/about/blob/master/CONTRIBUTING.md).
4 |
--------------------------------------------------------------------------------
/app/ui/app.html:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/ui/app.js:
--------------------------------------------------------------------------------
1 | import {inject} from 'aurelia-dependency-injection';
2 | import {Coordinator} from '../benchmarking/coordinator';
3 |
4 | @inject(Coordinator)
5 | export class App {
6 | constructor(coordinator) {
7 | this.coordinator = coordinator;
8 | }
9 |
10 | configureRouter(config, router){
11 | config.title = 'Benchmarks';
12 | config.map([
13 | { route: '', redirect: 'harness' },
14 | { route: 'harness', name: 'harness', moduleId: 'ui/harness/harness', nav: true, title: 'Harness' },
15 | { route: 'tags', name: 'tags', moduleId: 'ui/tags/tags', nav: true, title: 'Tags' },
16 | ]);
17 |
18 | this.router = router;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/server/controllers/tags.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var router = express.Router();
3 | var directory = require('../fsutil/directory');
4 | var basePath = 'dist/tags/';
5 |
6 | router.get('/', function(request, response) {
7 | var name = 'tags.json';
8 | var options = {
9 | headers: { "Content-Type": "json" },
10 | root: __dirname + "/../../" + basePath
11 | };
12 | response.sendFile(name, options);
13 | });
14 |
15 | router.post('/', function(request, response) {
16 | var name = 'tags.json';
17 | var results = request.body;
18 | directory.make(basePath);
19 | directory.writeFile(basePath + name, JSON.stringify(results, null, 2));
20 | response.end();
21 | });
22 |
23 | module.exports = router;
24 |
--------------------------------------------------------------------------------
/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Benchmarks
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/ui/tags/chart.js:
--------------------------------------------------------------------------------
1 | import {inject, customElement, bindable, noView, processContent} from 'aurelia-framework';
2 | import Chartist from 'chartist';
3 |
4 | @customElement('chart')
5 | @inject(Element)
6 | @noView()
7 | @processContent(false)
8 | export class Chart {
9 | @bindable data;
10 | @bindable options;
11 | @bindable type;
12 | chart = null;
13 |
14 | constructor(element) {
15 | this.element = element;
16 | }
17 |
18 | propertyChanged(name, newValue, oldValue) {
19 | if (this.chart) {
20 | this.chart.detach();
21 | this.chart = null;
22 | }
23 | if (this.data && this.options && this.type) {
24 | this.chart = Chartist[this.type](this.element, this.data, this.options);
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/benchmarking/definition-repository.js:
--------------------------------------------------------------------------------
1 | import {Definition} from './definition';
2 | import {type} from './type';
3 | import {HttpClient} from 'aurelia-http-client';
4 | import {inject} from 'aurelia-dependency-injection';
5 | import {parseJson} from '../util/parse-json';
6 |
7 | @inject(HttpClient)
8 | export class DefinitionRepository {
9 | definitions = null;
10 |
11 | constructor(http) {
12 | this.http = http;
13 | }
14 |
15 | load() {
16 | return this.http.get('/api/tests')
17 | .then(message => {
18 | let result = parseJson(message.response);
19 |
20 | this.definitions = result.micro.map(name => new Definition(name, type.micro))
21 | .concat(result.macro.map(name => new Definition(name, type.macro)));
22 | });
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/server/fsutil/directory.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs');
2 | var mkdirp = require('mkdirp');
3 |
4 | var getChildren = function(directory) {
5 | var base = __dirname + "/../.." + directory;
6 | return fs.readdirSync(base).filter(function(file) {
7 | return fs.statSync(base + '/' + file).isDirectory();
8 | });
9 | };
10 |
11 | var getFileNames = function(directory) {
12 | return fs.readdirSync(directory);
13 | };
14 |
15 | var make = function(path) {
16 | mkdirp.sync(path);
17 | };
18 |
19 | var writeFile = function(path, contents) {
20 | fs.writeFileSync(path, contents);
21 | };
22 |
23 | module.exports = {
24 | getChildren: getChildren,
25 | make: make,
26 | writeFile: writeFile,
27 | getFileNames: getFileNames,
28 | exists: function(path) { return fs.existsSync(path); }
29 | };
30 |
--------------------------------------------------------------------------------
/app/ui/harness/result-set.js:
--------------------------------------------------------------------------------
1 | import {bindable, customElement} from 'aurelia-framework';
2 |
3 | @customElement('result-set')
4 | export class ResultSet {
5 | @bindable results;
6 |
7 | getTextClass(result, field) {
8 | let change = this.compare(result, field);
9 | return !change || change.same ? 'text-muted' : (change.improved ? 'text-success' : 'text-danger');
10 | }
11 |
12 | compare(result, field) {
13 | var previous = this.getPrevious(result);
14 | if (previous) {
15 | let p = (result[field] - previous[field]) / previous[field] * 100;
16 | return {
17 | same: Math.abs(p) <= 15,
18 | improved: p < -15,
19 | percentImprovement: p
20 | }
21 | }
22 | return null;
23 | }
24 |
25 | getPrevious(result) {
26 | let i = this.results.indexOf(result);
27 | return this.results[i + 1];
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/main.js:
--------------------------------------------------------------------------------
1 | import {HttpClient} from 'aurelia-http-client';
2 |
3 | export function configure(aurelia) {
4 | aurelia.use
5 | .standardConfiguration()
6 | .developmentLogging()
7 | .feature('./resources')
8 | .feature('./benchmark-resources');
9 |
10 | // configure the http client.
11 | let http = aurelia.container.get(HttpClient);
12 | http.configure(x => x.withHeader('Content-Type', 'application/json'));
13 | aurelia.container.registerInstance(HttpClient, http);
14 |
15 | // register the iframe element used by the macro benchmark runner.
16 | let iframe = document.createElement('iframe');
17 | iframe.style.display = 'none';
18 | aurelia.container.registerInstance(HTMLIFrameElement, iframe);
19 |
20 | aurelia.start().then(a => a.setRoot('ui/app'))
21 | .then(() => document.body.appendChild(iframe)); // add the iframe to the body after the app is composed.
22 | }
23 |
--------------------------------------------------------------------------------
/app/benchmarking/macro-runner.js:
--------------------------------------------------------------------------------
1 | import {inject} from 'aurelia-dependency-injection';
2 |
3 | @inject(HTMLIFrameElement)
4 | export class MacroRunner {
5 | constructor(iframe) {
6 | this.iframe = iframe;
7 | }
8 |
9 | run(name) {
10 | return new Promise((resolve, reject) => {
11 | let start, finish;
12 |
13 | let handleMessage = event => {
14 | if (event.data === 'test-start') {
15 | start = new Date();
16 | return;
17 | }
18 | if (event.data !== 'test-end') {
19 | return;
20 | }
21 | finish = new Date();
22 |
23 | window.removeEventListener('message', handleMessage)
24 | this.iframe.src = 'about:blank';
25 |
26 | resolve({ period: (finish - start) / 1000.0, heapDeltas: [] });
27 | };
28 |
29 | window.addEventListener('message', handleMessage);
30 | this.iframe.src = `/benchmarks/macro/${name}/index.html`;
31 | });
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2010 - 2016 Blue Spire Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/benchmarks/micro/binding-parse-complex/index.js:
--------------------------------------------------------------------------------
1 | import {Parser} from 'aurelia-framework';
2 |
3 | var expressions = [], i;
4 |
5 | for(i = 0; i < 100; i++) {
6 | expressions.push('a.path.expression' + i);
7 | expressions.push('accessKeyedExpression[' + i + ']');
8 | expressions.push('accessKeyedExpression[' + i + '].and.a.path.expression');
9 | expressions.push('callScopeExpression' + i + '()');
10 | expressions.push('callScopeExpression(' + i + ')');
11 | expressions.push('callMember.expression(' + i + ')');
12 | expressions.push('callMember.expression(' + i + ', true, false, 1, \'hello world\')');
13 | expressions.push('a' + i + ' ? conditional : expression');
14 | expressions.push('another ? more.complex : conditional[' + i + '].expression');
15 | expressions.push('a' + i + ' | converter:expression');
16 | expressions.push('another.more[' + i + '].complex | converter:expression:' + i);
17 | }
18 |
19 | export default deferred => {
20 | var parser = new Parser(), expression;
21 | i = expressions.length;
22 | while(i--) {
23 | expression = expressions[i];
24 | parser.parse(expression);
25 | }
26 | deferred.resolve();
27 | };
28 |
--------------------------------------------------------------------------------
/app/benchmarking/coordinator.js:
--------------------------------------------------------------------------------
1 | import {inject} from 'aurelia-dependency-injection';
2 | import {type} from './type';
3 | import {MicroRunner} from './micro-runner';
4 | import {MacroRunner} from './macro-runner';
5 | import {ResultFactory} from './result-factory';
6 | import {ResultRepository} from './result-repository';
7 |
8 | @inject(MicroRunner, MacroRunner, ResultFactory, ResultRepository)
9 | export class Coordinator {
10 | promise = Promise.resolve(null);
11 | active = null;
12 |
13 | constructor(micro, macro, resultFactory, results) {
14 | this.micro = micro;
15 | this.macro = macro;
16 | this.resultFactory = resultFactory;
17 | this.results = results;
18 | }
19 |
20 | enqueue(definition) {
21 | this.promise = this.promise.then(() => {
22 | this.active = definition;
23 | let runner = definition.type === type.micro ? this.micro : this.macro;
24 | return runner.run(definition.name)
25 | .then(measures => {
26 | let result = this.resultFactory.fromMeasures(definition.name, measures);
27 | this.results.add(result);
28 | this.active = null;
29 | });
30 | });
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/ui/harness/harness.js:
--------------------------------------------------------------------------------
1 | import {inject} from 'aurelia-dependency-injection';
2 | import {Coordinator} from '../../benchmarking/coordinator';
3 | import {DefinitionRepository} from '../../benchmarking/definition-repository';
4 | import {ResultRepository} from '../../benchmarking/result-repository';
5 | import {BenchmarkViewModel} from '../benchmark-view-model';
6 |
7 | @inject(DefinitionRepository, ResultRepository, Coordinator)
8 | export class Harness extends BenchmarkViewModel {
9 | isTagging = false;
10 |
11 | constructor(definitionRepository, resultRepository, coordinator) {
12 | super(definitionRepository, resultRepository);
13 | this.coordinator = coordinator;
14 | }
15 |
16 | run() {
17 | this.selectedDefinitions.forEach(::this.coordinator.enqueue);
18 | }
19 |
20 | tag(tag) {
21 | let names = this.selectedDefinitions.map(d => d.name);
22 | this.isTagging = true;
23 | this.resultRepository.tag(names, tag)
24 | .then(() => this.isTagging = false);
25 | }
26 |
27 | definitionClicked(definition, event) {
28 | let index = this.selectedDefinitions.indexOf(definition);
29 | if (index === -1) {
30 | this.selectedDefinitions.push(definition);
31 | } else {
32 | this.selectedDefinitions.splice(index, 1);
33 | }
34 | }
35 |
36 | canDeactivate() {
37 | return this.coordinator.active === null;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/benchmarks/micro/binding-interpolation-short/index.js:
--------------------------------------------------------------------------------
1 | import {TemplatingBindingLanguage} from 'aurelia-templating-binding';
2 |
3 | var parser = { parse: expression => null },
4 | observerLocator = { getObserver: () => null },
5 | syntaxInterpreter = {},
6 | language = new TemplatingBindingLanguage(parser, observerLocator, syntaxInterpreter),
7 | resources = { valueConverterLookupFunction: () => null },
8 | expressions = [
9 | '${name}',
10 | '${\'foo\\\'\'}',
11 | '${name}',
12 | '${\'name\'}',
13 | '${\'name\\\'\'}',
14 | '${"name"}',
15 | '${"name\\\""}',
16 | '\\${name}',
17 | '\\\\${"name"}',
18 | 'foo${name}baz',
19 | ' ${name} ',
20 | '\'${name}\'',
21 | '"${name}"',
22 | 'foo bar baz',
23 | '${foo.bar.baz}',
24 | '${ name }',
25 | '${name | foo}',
26 | '${name | foo:bar}',
27 | '${name|test:{}}',
28 | '${name|test:\'{}\'}',
29 | '${name | test: { foo: 4, bar, 9 } }',
30 | 'foo ${name | test: { foo: 4, bar, 9 } } bar',
31 | '${firstName}${lastName}',
32 | ' ${firstName} ${lastName} ',
33 | '\\ ${foo}\\',
34 | ];
35 |
36 | export default deferred => {
37 | var i = expressions.length, j, expression;
38 | while(i--) {
39 | expression = expressions[i];
40 | j = 100;
41 | while(j--) {
42 | language.parseContent(resources, 'textContent', expression);
43 | }
44 | }
45 | deferred.resolve();
46 | }
47 |
--------------------------------------------------------------------------------
/app/benchmarking/micro-runner.js:
--------------------------------------------------------------------------------
1 | import {Benchmark} from 'benchmark';
2 |
3 | // benchmark.js expects a global Benchmark object and at least one