feat(compiler): add benchmarks
- compileEmptyTemplate - compile25ElementsNoBindings - compile25ElementsWithBindings For the results see the PR #197. Closes #197
This commit is contained in:
parent
aa9eeb80e7
commit
b07ea6b90e
|
@ -0,0 +1,36 @@
|
|||
library compiler_benchmark;
|
||||
|
||||
import './selector_benchmark.dart' as sbm;
|
||||
import './compiler_benchmark.dart' as cbm;
|
||||
import 'dart:js' as js;
|
||||
|
||||
main () {
|
||||
sbm.setup();
|
||||
cbm.setup();
|
||||
|
||||
js.context['benchmarkSteps'].add(new js.JsObject.jsify({
|
||||
"name": "CssSelector.parse * 1000",
|
||||
"fn": new js.JsFunction.withThis((_) => sbm.runParse())
|
||||
}));
|
||||
js.context['benchmarkSteps'].add(new js.JsObject.jsify({
|
||||
"name": "SelectorMatcher.addSelectable * 1000",
|
||||
"fn": new js.JsFunction.withThis((_) => sbm.runAdd())
|
||||
}));
|
||||
js.context['benchmarkSteps'].add(new js.JsObject.jsify({
|
||||
"name": "SelectorMatcher.match * 1000",
|
||||
"fn": new js.JsFunction.withThis((_) => sbm.runMatch())
|
||||
}));
|
||||
|
||||
js.context['benchmarkSteps'].add(new js.JsObject.jsify({
|
||||
"name": "Compiler.compile empty template",
|
||||
"fn": new js.JsFunction.withThis((_) => cbm.compileEmptyTemplate())
|
||||
}));
|
||||
js.context['benchmarkSteps'].add(new js.JsObject.jsify({
|
||||
"name": "Compiler.compile 25 element no bindings",
|
||||
"fn": new js.JsFunction.withThis((_) => cbm.compile25ElementsNoBindings())
|
||||
}));
|
||||
js.context['benchmarkSteps'].add(new js.JsObject.jsify({
|
||||
"name": "Compiler.compile 25 element with bindings",
|
||||
"fn": new js.JsFunction.withThis((_) => cbm.compile25ElementsWithBindings())
|
||||
}));
|
||||
}
|
|
@ -1,17 +1,35 @@
|
|||
System.import('benchmarks/compiler/selector_benchmark').then(function (bm) {
|
||||
bm.setup();
|
||||
|
||||
window.benchmarkSteps.push({name: 'CssSelector.parse', fn: bm.runParse});
|
||||
window.benchmarkSteps.push({name: 'CssSelector.parse * 1000', fn: bm.runParse});
|
||||
}, console.log.bind(console));
|
||||
|
||||
System.import('benchmarks/compiler/selector_benchmark').then(function (bm) {
|
||||
bm.setup();
|
||||
|
||||
window.benchmarkSteps.push({name: 'SelectorMatcher.addSelectable', fn: bm.runAdd});
|
||||
window.benchmarkSteps.push({name: 'SelectorMatcher.addSelectable * 1000', fn: bm.runAdd});
|
||||
}, console.log.bind(console));
|
||||
|
||||
System.import('benchmarks/compiler/selector_benchmark').then(function (bm) {
|
||||
bm.setup();
|
||||
|
||||
window.benchmarkSteps.push({name: 'SelectorMatcher.match', fn: bm.runMatch});
|
||||
window.benchmarkSteps.push({name: 'SelectorMatcher.match * 1000', fn: bm.runMatch});
|
||||
}, console.log.bind(console));
|
||||
|
||||
System.import('benchmarks/compiler/compiler_benchmark').then(function (bm) {
|
||||
bm.setup();
|
||||
|
||||
window.benchmarkSteps.push({name: 'Compiler.compile empty template', fn: bm.compileEmptyTemplate});
|
||||
}, console.log.bind(console));
|
||||
|
||||
System.import('benchmarks/compiler/compiler_benchmark').then(function (bm) {
|
||||
bm.setup();
|
||||
|
||||
window.benchmarkSteps.push({name: 'Compiler.compile 25 element no bindings', fn: bm.compile25ElementsNoBindings});
|
||||
}, console.log.bind(console));
|
||||
|
||||
System.import('benchmarks/compiler/compiler_benchmark').then(function (bm) {
|
||||
bm.setup();
|
||||
|
||||
window.benchmarkSteps.push({name: 'Compiler.compile 25 element with bindings', fn: bm.compile25ElementsWithBindings});
|
||||
}, console.log.bind(console));
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
import {DOM} from 'facade/dom';
|
||||
|
||||
import {Parser} from 'change_detection/parser/parser';
|
||||
import {ClosureMap} from 'change_detection/parser/closure_map';
|
||||
import {Lexer} from 'change_detection/parser/lexer';
|
||||
|
||||
import {Compiler} from 'core/compiler/compiler';
|
||||
import {Reflector} from 'core/compiler/reflector';
|
||||
|
||||
import {Component} from 'core/annotations/component';
|
||||
import {Decorator} from 'core/annotations/decorator';
|
||||
import {TemplateConfig} from 'core/annotations/template_config';
|
||||
|
||||
var compiler;
|
||||
var annotatedComponent;
|
||||
var annotatedComponentNoDirectives;
|
||||
|
||||
var emptyTemplate;
|
||||
var templateWith25ElementsNoBindings;
|
||||
var templateWith25ElementsAndBindings;
|
||||
|
||||
export function setup() {
|
||||
var closureMap = new ClosureMap();
|
||||
var reflector = new Reflector();
|
||||
compiler = new Compiler(null, reflector, new Parser(new Lexer(), closureMap), closureMap);
|
||||
annotatedComponent = reflector.annotatedType(SomeComponent);
|
||||
annotatedComponentNoDirectives = reflector.annotatedType(ComponentWithNoDirectives);
|
||||
|
||||
emptyTemplate = createTemplate('<div></div>');
|
||||
templateWith25ElementsNoBindings = buildTemplateWith25ElementsNoBindings();
|
||||
templateWith25ElementsAndBindings = buildTemplateWith25ElementsAndBindings();
|
||||
}
|
||||
|
||||
export function compileEmptyTemplate() {
|
||||
var template = emptyTemplate;
|
||||
return compiler.compileWithCache(null, annotatedComponent, template);
|
||||
}
|
||||
|
||||
export function compile25ElementsWithBindings() {
|
||||
var template = templateWith25ElementsAndBindings;
|
||||
return compiler.compileWithCache(null, annotatedComponent, template);
|
||||
}
|
||||
|
||||
export function compile25ElementsNoBindings() {
|
||||
var template = templateWith25ElementsNoBindings;
|
||||
return compiler.compileWithCache(null, annotatedComponentNoDirectives, template);
|
||||
}
|
||||
|
||||
@Decorator({
|
||||
selector: '[dir0]',
|
||||
bind: {
|
||||
'attr0': 'prop'
|
||||
}
|
||||
})
|
||||
class Dir0 {}
|
||||
|
||||
@Decorator({
|
||||
selector: '[dir1]',
|
||||
bind: {
|
||||
'attr1': 'prop'
|
||||
}
|
||||
})
|
||||
class Dir1 {}
|
||||
|
||||
@Decorator({
|
||||
selector: '[dir2]',
|
||||
bind: {
|
||||
'attr2': 'prop'
|
||||
}
|
||||
})
|
||||
class Dir2 {}
|
||||
|
||||
@Decorator({
|
||||
selector: '[dir3]',
|
||||
bind: {
|
||||
'attr3': 'prop'
|
||||
}
|
||||
})
|
||||
class Dir3 {}
|
||||
|
||||
@Decorator({
|
||||
selector: '[dir4]',
|
||||
bind: {
|
||||
'attr4': 'prop'
|
||||
}
|
||||
})
|
||||
class Dir4 {}
|
||||
|
||||
@Component({
|
||||
template: new TemplateConfig({
|
||||
directives: [Dir0, Dir1, Dir2, Dir3, Dir4]
|
||||
})
|
||||
})
|
||||
class SomeComponent {}
|
||||
|
||||
@Component({
|
||||
template: new TemplateConfig({
|
||||
directives: []
|
||||
})
|
||||
})
|
||||
class ComponentWithNoDirectives {}
|
||||
|
||||
// creates 25 nested divs without bindings, each looking like this:
|
||||
// <div class="class0 class1 class2 class3 class4 " dir0="" attr0="value0" dir1="" attr1="value1" dir2="" attr2="value2" dir3="" attr3="value3" dir4="" attr4="value4">
|
||||
// </div>
|
||||
function buildTemplateWith25ElementsNoBindings() {
|
||||
var result = '';
|
||||
for (var i=0; i<5; i++) {
|
||||
for (var j=0; j<5; j++) {
|
||||
result += '<div class="';
|
||||
for (var k=0; k<5; k++) {
|
||||
result += `class${k} `;
|
||||
}
|
||||
result += '"';
|
||||
for (var k=0; k<5; k++) {
|
||||
result += ` dir${k}`;
|
||||
result += ` attr${k}=value${k}`;
|
||||
}
|
||||
for (var k=0; k<5; k++) {
|
||||
result += ` dir${k}`;
|
||||
result += ` attr${k}=value${k}`;
|
||||
}
|
||||
result += '>';
|
||||
}
|
||||
for (var j=0; j<5; j++) {
|
||||
result += '</div>';
|
||||
}
|
||||
}
|
||||
return createTemplate(result);
|
||||
}
|
||||
|
||||
// creates 25 nested divs , each looking like this:
|
||||
// <div class="class0 class1 class2 class3 class4 " dir0="" [attr0]="value0" dir1="" [attr1]="value1" dir2="" [attr2]="value2" dir3="" [attr3]="value3" dir4="" [attr4]="value4">
|
||||
// {{inter0}}{{inter1}}{{inter2}}{{inter3}}{{inter4}}
|
||||
// </div>
|
||||
function buildTemplateWith25ElementsAndBindings() {
|
||||
var result = '';
|
||||
for (var i=0; i<5; i++) {
|
||||
for (var j=0; j<5; j++) {
|
||||
result += '<div class="';
|
||||
for (var k=0; k<5; k++) {
|
||||
result += `class${k} `;
|
||||
}
|
||||
result += '"';
|
||||
for (var k=0; k<5; k++) {
|
||||
result += ` dir${k}`;
|
||||
result += ` [attr${k}]=value${k}`;
|
||||
}
|
||||
for (var k=0; k<5; k++) {
|
||||
result += ` dir${k}`;
|
||||
result += ` [attr${k}]=value${k}`;
|
||||
}
|
||||
result += '>';
|
||||
for (var k=0; k<5; k++) {
|
||||
result += `{{inter${k}}}`;
|
||||
}
|
||||
}
|
||||
for (var j=0; j<5; j++) {
|
||||
result += '</div>';
|
||||
}
|
||||
}
|
||||
return createTemplate(result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function createTemplate(html) {
|
||||
return DOM.createTemplate(html);
|
||||
}
|
|
@ -31,13 +31,11 @@ export function runParse() {
|
|||
}
|
||||
|
||||
export function runAdd() {
|
||||
// The sum is used to prevent Chrome from optimizing the loop away...
|
||||
var matcher = new SelectorMatcher();
|
||||
var count = 0;
|
||||
for (var i=0; i<COUNT; i++) {
|
||||
count += matcher.addSelectable(fixedSelectors[i], i);
|
||||
matcher.addSelectable(fixedSelectors[i], i);
|
||||
}
|
||||
return count;
|
||||
return matcher;
|
||||
}
|
||||
|
||||
export function runMatch() {
|
||||
|
@ -72,7 +70,7 @@ function randomStr(len){
|
|||
|
||||
function randomChar(){
|
||||
var n = randomNum(62);
|
||||
if(n<10) return n; //1-10
|
||||
if(n<10) return n.toString(); //1-10
|
||||
if(n<36) return StringWrapper.fromCharCode(n+55); //A-Z
|
||||
return StringWrapper.fromCharCode(n+61); //a-z
|
||||
}
|
||||
|
|
|
@ -39,14 +39,13 @@ export class Compiler {
|
|||
compile(component:Type, templateRoot:Element = null):Promise<ProtoView> {
|
||||
// TODO load all components transitively from the cache first
|
||||
var cache = null;
|
||||
return PromiseWrapper.resolve(this._compileAllCached(
|
||||
this._reflector.annotatedType(component),
|
||||
cache,
|
||||
templateRoot)
|
||||
return PromiseWrapper.resolve(this.compileWithCache(
|
||||
cache, this._reflector.annotatedType(component), templateRoot)
|
||||
);
|
||||
}
|
||||
|
||||
_compileAllCached(component:AnnotatedType, cache, templateRoot:Element = null):ProtoView {
|
||||
// public so that we can compile in sync in performance tests.
|
||||
compileWithCache(cache, component:AnnotatedType, templateRoot:Element = null):ProtoView {
|
||||
if (isBlank(templateRoot)) {
|
||||
// TODO: read out the cache if templateRoot = null. Could contain:
|
||||
// - templateRoot string
|
||||
|
@ -62,7 +61,7 @@ export class Compiler {
|
|||
for (var i=0; i<compileElements.length; i++) {
|
||||
var ce = compileElements[i];
|
||||
if (isPresent(ce.componentDirective)) {
|
||||
ce.inheritedElementBinder.nestedProtoView = this._compileAllCached(ce.componentDirective, cache, null);
|
||||
ce.inheritedElementBinder.nestedProtoView = this.compileWithCache(cache, ce.componentDirective, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
library facade.di.reflector;
|
||||
library facade.compiler.reflector;
|
||||
|
||||
import 'dart:mirrors';
|
||||
import '../annotations/directive.dart';
|
||||
|
|
Loading…
Reference in New Issue