refactor(benchmark): simplify writing benchmarks
Adds `benchmarks/benchpress` module and adjusts the compiler benchmarks to use it. Also adds the Angular 1.3 benchmark to the compiler benchmarks. Closes #202
This commit is contained in:
parent
be4cb2db3a
commit
8dfbc242af
|
@ -0,0 +1,63 @@
|
|||
library benchmarks.benchpress;
|
||||
|
||||
import 'dart:js' as js;
|
||||
import 'dart:html';
|
||||
import 'dart:async';
|
||||
|
||||
// TODO: move the functionality of this module into benchpress and replace this
|
||||
// file with a Dart wrapper!
|
||||
|
||||
var _benchmarkNames = [];
|
||||
|
||||
_benchmarkId(index) {
|
||||
return "benchmark${index}";
|
||||
}
|
||||
|
||||
_useBenchmark(index) {
|
||||
var search = window.location.search;
|
||||
if (search.length > 0) {
|
||||
search = search.substring(1);
|
||||
}
|
||||
if (search.length > 0) {
|
||||
return search == _benchmarkId(index);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
_onLoad(callback) {
|
||||
var isReady = document.readyState == 'complete';
|
||||
if (isReady) {
|
||||
Timer.run(callback);
|
||||
} else {
|
||||
window.addEventListener('load', (event) => callback(), false);
|
||||
}
|
||||
}
|
||||
|
||||
_createBenchmarkMenu() {
|
||||
var div = document.createElement('div');
|
||||
div.innerHtml += '<h1>Benchmarks:</h1><a class="btn btn-default" href="?">All</a>';
|
||||
for (var i=0; i<_benchmarkNames.length; i++) {
|
||||
var activeClass = _useBenchmark(i) ? 'active' : '';
|
||||
div.innerHtml += '<a class="btn btn-default ${activeClass}" href="?${_benchmarkId(i)}">${_benchmarkNames[i]}</a>';
|
||||
}
|
||||
document.body.insertBefore(div, document.body.childNodes[0]);
|
||||
}
|
||||
|
||||
benchmark(name, stepsCreationCallback) {
|
||||
_benchmarkNames.add(name);
|
||||
if (_benchmarkNames.length == 2) {
|
||||
_onLoad(_createBenchmarkMenu);
|
||||
}
|
||||
if (_useBenchmark(_benchmarkNames.length-1)) {
|
||||
stepsCreationCallback();
|
||||
}
|
||||
}
|
||||
|
||||
benchmarkStep(name, callback) {
|
||||
var benchmarkName = _benchmarkNames[_benchmarkNames.length-1];
|
||||
js.context['benchmarkSteps'].add(new js.JsObject.jsify({
|
||||
"name": benchmarkName + '#' + name,
|
||||
"fn": new js.JsFunction.withThis((_) => callback())
|
||||
}));
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
// TODO: move the functionality of this module into benchpress itself!
|
||||
|
||||
var benchmarkNames = [];
|
||||
|
||||
function benchmarkId(index) {
|
||||
return 'benchmark' + index;
|
||||
}
|
||||
|
||||
function useBenchmark(index) {
|
||||
var search = window.location.search;
|
||||
if (search.length > 0) {
|
||||
search = search.substring(1);
|
||||
}
|
||||
if (search.length > 0) {
|
||||
return search == benchmarkId(index);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function onLoad(callback) {
|
||||
var isReady = document.readyState === 'complete';
|
||||
if (isReady) {
|
||||
window.setTimeout(callback);
|
||||
} else {
|
||||
window.addEventListener('load', callback, false);
|
||||
}
|
||||
}
|
||||
|
||||
function createBenchmarkMenu() {
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML += '<h1>Benchmarks:</h1><a class="btn btn-default" href="?">All</a>';
|
||||
for (var i=0; i<benchmarkNames.length; i++) {
|
||||
var activeClass = useBenchmark(i) ? 'active' : '';
|
||||
div.innerHTML += ('<a class="btn btn-default '+activeClass+'" href="?'+benchmarkId(i)+'">'+benchmarkNames[i]+'</a>');
|
||||
}
|
||||
document.body.insertBefore(div, document.body.childNodes[0]);
|
||||
}
|
||||
|
||||
export function benchmark(name, stepsCreationCallback) {
|
||||
benchmarkNames.push(name);
|
||||
if (benchmarkNames.length === 2) {
|
||||
onLoad(createBenchmarkMenu);
|
||||
}
|
||||
if (useBenchmark(benchmarkNames.length-1)) {
|
||||
stepsCreationCallback();
|
||||
}
|
||||
}
|
||||
|
||||
export function benchmarkStep(name, callback) {
|
||||
var benchmarkName = benchmarkNames[benchmarkNames.length-1];
|
||||
window.benchmarkSteps.push({
|
||||
name: benchmarkName + '#' + name, fn: callback
|
||||
});
|
||||
}
|
|
@ -2,35 +2,8 @@ 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())
|
||||
}));
|
||||
sbm.main();
|
||||
cbm.main();
|
||||
}
|
|
@ -1,35 +1,9 @@
|
|||
System.import('benchmarks/compiler/selector_benchmark').then(function (bm) {
|
||||
bm.setup();
|
||||
|
||||
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 * 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 * 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});
|
||||
Promise.all([
|
||||
System.import('benchmarks/compiler/selector_benchmark'),
|
||||
System.import('benchmarks/compiler/compiler_benchmark'),
|
||||
System.import('benchmarks/compiler/compiler_benchmark_ng13')
|
||||
]).then(function (benchmarks) {
|
||||
benchmarks.forEach(function(bm) {
|
||||
bm.main();
|
||||
});
|
||||
}, console.log.bind(console));
|
||||
|
|
|
@ -4,7 +4,8 @@ module.exports = function(config) {
|
|||
{src: '/js/traceur-runtime.js'},
|
||||
{src: '/js/es6-module-loader-sans-promises.src.js'},
|
||||
{src: '/js/extension-register.js'},
|
||||
{src: 'register_system.js'},
|
||||
{src: 'paths.js'},
|
||||
{src: 'https://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.js'},
|
||||
{src: 'benchmark.js'}
|
||||
]
|
||||
});
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
import {DOM} from 'facade/dom';
|
||||
import {benchmark, benchmarkStep} from '../benchpress';
|
||||
|
||||
import {DOM, document} from 'facade/dom';
|
||||
import {isBlank} from 'facade/lang';
|
||||
import {MapWrapper} from 'facade/collection';
|
||||
import {AnnotatedType} from 'core/compiler/annotated_type';
|
||||
|
||||
import {Parser} from 'change_detection/parser/parser';
|
||||
import {ClosureMap} from 'change_detection/parser/closure_map';
|
||||
|
@ -11,39 +16,65 @@ import {Component} from 'core/annotations/component';
|
|||
import {Decorator} from 'core/annotations/decorator';
|
||||
import {TemplateConfig} from 'core/annotations/template_config';
|
||||
|
||||
var COUNT = 30;
|
||||
|
||||
var compiler;
|
||||
var annotatedComponent;
|
||||
var annotatedComponentNoDirectives;
|
||||
|
||||
var emptyTemplate;
|
||||
var templateWith25ElementsNoBindings;
|
||||
var templateWith25ElementsAndBindings;
|
||||
|
||||
export function setup() {
|
||||
function setup() {
|
||||
var closureMap = new ClosureMap();
|
||||
var reflector = new Reflector();
|
||||
var reflector = new CachingReflector();
|
||||
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();
|
||||
annotatedComponent = reflector.annotatedType(BenchmarkComponent);
|
||||
}
|
||||
|
||||
export function compileEmptyTemplate() {
|
||||
var template = emptyTemplate;
|
||||
return compiler.compileWithCache(null, annotatedComponent, template);
|
||||
export function main() {
|
||||
setup();
|
||||
|
||||
benchmark(`Compiler.compile 5*${COUNT} element no bindings`, function() {
|
||||
var template = loadTemplate('templateNoBindings', COUNT);
|
||||
|
||||
benchmarkStep('run', function() {
|
||||
// Need to clone every time as the compiler might modify the template!
|
||||
var cloned = DOM.clone(template);
|
||||
compiler.compileWithCache(null, annotatedComponent, cloned);
|
||||
});
|
||||
});
|
||||
|
||||
benchmark(`Compiler.compile 5*${COUNT} element with bindings`, function() {
|
||||
var template = loadTemplate('templateWithBindings', COUNT);
|
||||
|
||||
benchmarkStep('run', function() {
|
||||
// Need to clone every time as the compiler might modify the template!
|
||||
var cloned = DOM.clone(template);
|
||||
compiler.compileWithCache(null, annotatedComponent, cloned);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function compile25ElementsWithBindings() {
|
||||
var template = templateWith25ElementsAndBindings;
|
||||
return compiler.compileWithCache(null, annotatedComponent, template);
|
||||
function loadTemplate(templateId, repeatCount) {
|
||||
var template = DOM.querySelectorAll(document, `#${templateId}`)[0];
|
||||
var content = DOM.getInnerHTML(template);
|
||||
var result = '';
|
||||
for (var i=0; i<repeatCount; i++) {
|
||||
result += content;
|
||||
}
|
||||
return DOM.createTemplate(result);
|
||||
}
|
||||
|
||||
export function compile25ElementsNoBindings() {
|
||||
var template = templateWith25ElementsNoBindings;
|
||||
return compiler.compileWithCache(null, annotatedComponentNoDirectives, template);
|
||||
// Caching reflector as reflection in Dart using Mirrors
|
||||
class CachingReflector extends Reflector {
|
||||
constructor() {
|
||||
this._cache = MapWrapper.create();
|
||||
}
|
||||
annotatedType(type:Type):AnnotatedType {
|
||||
var result = MapWrapper.get(this._cache, type);
|
||||
if (isBlank(result)) {
|
||||
result = super.annotatedType(type);
|
||||
MapWrapper.set(this._cache, type, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Decorator({
|
||||
|
@ -91,79 +122,5 @@ class Dir4 {}
|
|||
directives: [Dir0, Dir1, Dir2, Dir3, Dir4]
|
||||
})
|
||||
})
|
||||
class SomeComponent {}
|
||||
class BenchmarkComponent {}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
import {benchmark, benchmarkStep} from '../benchpress';
|
||||
|
||||
var COUNT = 30;
|
||||
var $compile;
|
||||
|
||||
export function main() {
|
||||
|
||||
benchmark(`Ng 1.3 Compiler.compile 5*${COUNT} element no bindings`, function() {
|
||||
var template = loadTemplate('templateNoBindings', COUNT);
|
||||
|
||||
benchmarkStep('run', function() {
|
||||
// Need to clone every time as the compiler might modify the template!
|
||||
var cloned = template.cloneNode(true);
|
||||
$compile(cloned);
|
||||
});
|
||||
});
|
||||
|
||||
benchmark(`Ng 1.3 Compiler.compile 5*${COUNT} element with bindings`, function() {
|
||||
var template = loadTemplate('templateWithBindings', COUNT);
|
||||
|
||||
benchmarkStep('run', function() {
|
||||
// Need to clone every time as the compiler might modify the template!
|
||||
var cloned = template.cloneNode(true);
|
||||
$compile(cloned);
|
||||
});
|
||||
});
|
||||
|
||||
var ngEl = document.createElement('div');
|
||||
angular.bootstrap(ngEl, ['app']);
|
||||
}
|
||||
|
||||
function loadTemplate(templateId, repeatCount) {
|
||||
var template = document.querySelectorAll(`#${templateId}`)[0];
|
||||
var content = template.innerHTML;
|
||||
var result = '';
|
||||
for (var i=0; i<repeatCount; i++) {
|
||||
result += content;
|
||||
}
|
||||
// replace [] binding syntax
|
||||
result = result.replace(/[\[\]]/g, '');
|
||||
|
||||
// Use a DIV as container as Angular 1.3 does not know <template> elements...
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = result;
|
||||
return div;
|
||||
}
|
||||
|
||||
angular.module('app', [])
|
||||
.directive('dir0', function($parse) {
|
||||
return {
|
||||
compile: function($element, $attrs) {
|
||||
var expr = $parse($attrs.attr0);
|
||||
return function($scope) {
|
||||
$scope.$watch(expr, angular.noop);
|
||||
}
|
||||
}
|
||||
};
|
||||
})
|
||||
.directive('dir1', function($parse) {
|
||||
return {
|
||||
compile: function($element, $attrs) {
|
||||
var expr = $parse($attrs.attr1);
|
||||
return function($scope) {
|
||||
$scope.$watch(expr, angular.noop);
|
||||
}
|
||||
}
|
||||
};
|
||||
})
|
||||
.directive('dir2', function($parse) {
|
||||
return {
|
||||
compile: function($element, $attrs) {
|
||||
var expr = $parse($attrs.attr2);
|
||||
return function($scope) {
|
||||
$scope.$watch(expr, angular.noop);
|
||||
}
|
||||
}
|
||||
};
|
||||
})
|
||||
.directive('dir3', function($parse) {
|
||||
return {
|
||||
compile: function($element, $attrs) {
|
||||
var expr = $parse($attrs.attr3);
|
||||
return function($scope) {
|
||||
$scope.$watch(expr, angular.noop);
|
||||
}
|
||||
}
|
||||
};
|
||||
})
|
||||
.directive('dir4', function($parse) {
|
||||
return {
|
||||
compile: function($element, $attrs) {
|
||||
var expr = $parse($attrs.attr4);
|
||||
return function($scope) {
|
||||
$scope.$watch(expr, angular.noop);
|
||||
}
|
||||
}
|
||||
};
|
||||
})
|
||||
.run(function(_$compile_) {
|
||||
$compile = _$compile_;
|
||||
});
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<template id="templateNoBindings">
|
||||
<div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4">
|
||||
<div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4">
|
||||
<div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4">
|
||||
<div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4">
|
||||
<div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="templateWithBindings">
|
||||
<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 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 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 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 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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
|
@ -1,3 +1,5 @@
|
|||
import {benchmark, benchmarkStep} from '../benchpress';
|
||||
|
||||
import {SelectorMatcher} from "core/compiler/selector";
|
||||
import {CssSelector} from "core/compiler/selector";
|
||||
import {StringWrapper, Math} from 'facade/lang';
|
||||
|
@ -9,46 +11,55 @@ var fixedSelectors = [];
|
|||
|
||||
var COUNT = 1000;
|
||||
|
||||
export function setup() {
|
||||
for (var i=0; i<COUNT; i++) {
|
||||
export function main() {
|
||||
setup(COUNT);
|
||||
|
||||
benchmark(`cssSelector.parse * ${COUNT}`, function() {
|
||||
benchmarkStep(`run`, function() {
|
||||
var result = [];
|
||||
for (var i=0; i<COUNT; i++) {
|
||||
ListWrapper.push(result, CssSelector.parse(fixedSelectorStrings[i]));
|
||||
}
|
||||
return result;
|
||||
});
|
||||
});
|
||||
|
||||
benchmark(`cssSelector.addSelectable * ${COUNT}`, function() {
|
||||
benchmarkStep(`run`, function() {
|
||||
var matcher = new SelectorMatcher();
|
||||
for (var i=0; i<COUNT; i++) {
|
||||
matcher.addSelectable(fixedSelectors[i], i);
|
||||
}
|
||||
return matcher;
|
||||
});
|
||||
});
|
||||
|
||||
benchmark(`cssSelector.match * ${COUNT}`, function() {
|
||||
benchmarkStep(`run`, function() {
|
||||
var matchCount = 0;
|
||||
for (var i=0; i<COUNT; i++) {
|
||||
fixedMatcher.match(fixedSelectors[i], (selected) => {
|
||||
matchCount += selected;
|
||||
});
|
||||
}
|
||||
return matchCount;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function setup(count) {
|
||||
for (var i=0; i<count; i++) {
|
||||
ListWrapper.push(fixedSelectorStrings, randomSelector());
|
||||
}
|
||||
for (var i=0; i<COUNT; i++) {
|
||||
for (var i=0; i<count; i++) {
|
||||
ListWrapper.push(fixedSelectors, CssSelector.parse(fixedSelectorStrings[i]));
|
||||
}
|
||||
fixedMatcher = new SelectorMatcher();
|
||||
for (var i=0; i<COUNT; i++) {
|
||||
for (var i=0; i<count; i++) {
|
||||
fixedMatcher.addSelectable(fixedSelectors[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
export function runParse() {
|
||||
var result = [];
|
||||
for (var i=0; i<COUNT; i++) {
|
||||
ListWrapper.push(result, CssSelector.parse(fixedSelectorStrings[i]));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function runAdd() {
|
||||
var matcher = new SelectorMatcher();
|
||||
for (var i=0; i<COUNT; i++) {
|
||||
matcher.addSelectable(fixedSelectors[i], i);
|
||||
}
|
||||
return matcher;
|
||||
}
|
||||
|
||||
export function runMatch() {
|
||||
// The sum is used to prevent Chrome from optimizing the loop away...
|
||||
var count = 0;
|
||||
for (var i=0; i<COUNT; i++) {
|
||||
fixedMatcher.match(fixedSelectors[i], (selected) => {
|
||||
count += selected;
|
||||
});
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
function randomSelector() {
|
||||
var res = randomStr(5);
|
||||
for (var i=0; i<3; i++) {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
library change_detection.parser.closure_map;
|
||||
|
||||
import 'dart:mirrors';
|
||||
|
||||
typedef SetterFn(Object obj, value);
|
||||
|
|
|
@ -3,7 +3,7 @@ library angular.core.facade.dom;
|
|||
import 'dart:html';
|
||||
import 'dart:js' show JsObject;
|
||||
|
||||
export 'dart:html' show DocumentFragment, Node, Element, TemplateElement, Text;
|
||||
export 'dart:html' show DocumentFragment, Node, Element, TemplateElement, Text, document, location;
|
||||
|
||||
// TODO(tbosch): Is there a builtin one? Why is Dart
|
||||
// removing unknown elements by default?
|
||||
|
|
|
@ -4,6 +4,9 @@ export var NodeList = window.NodeList;
|
|||
export var Text = window.Text;
|
||||
export var Element = window.HTMLElement;
|
||||
export var TemplateElement = window.HTMLTemplateElement;
|
||||
export var document = window.document;
|
||||
export var location = window.location;
|
||||
|
||||
import {List, MapWrapper} from 'facade/collection';
|
||||
|
||||
export class DOM {
|
||||
|
|
Loading…
Reference in New Issue