refactor(perf): use webdriver to execute benchmarks
- use performance log of chromedriver / appium to get timeline data for calculating metrics for benchmarks - change all benchmarks to be made of a standalone application and a protractor test that collectes timeline data - fix and simplify benchmarks - add dart2js to build - remove benchpress Closes #330
This commit is contained in:
@ -1,4 +1,9 @@
|
||||
$SCRIPTS$
|
||||
<!doctype html>
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<button id="compileWithBindings">Compile template with bindings</button>
|
||||
<button id="compileNoBindings">Compile template without bindings</button>
|
||||
|
||||
<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">
|
||||
@ -30,3 +35,8 @@ $SCRIPTS$
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
$SCRIPTS$
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,5 +1,3 @@
|
||||
import {benchmark, benchmarkStep} from 'benchpress/benchpress';
|
||||
|
||||
import {DOM, document} from 'facade/dom';
|
||||
import {isBlank, Type} from 'facade/lang';
|
||||
import {MapWrapper} from 'facade/collection';
|
||||
@ -20,10 +18,7 @@ import {reflector} from 'reflection/reflection';
|
||||
|
||||
var COUNT = 30;
|
||||
|
||||
var compiler;
|
||||
var annotatedComponent;
|
||||
|
||||
function setup() {
|
||||
function setupReflector() {
|
||||
reflector.registerType(BenchmarkComponent, {
|
||||
"factory": () => new BenchmarkComponent(),
|
||||
"parameters": [],
|
||||
@ -79,47 +74,34 @@ function setup() {
|
||||
|
||||
"prop": (a,v) => a.prop = v
|
||||
});
|
||||
|
||||
var reader = new CachingDirectiveMetadataReader();
|
||||
compiler = new Compiler(null, reader, new Parser(new Lexer()), new CompilerCache());
|
||||
annotatedComponent = reader.annotatedType(BenchmarkComponent);
|
||||
}
|
||||
|
||||
export function main() {
|
||||
setup();
|
||||
setupReflector();
|
||||
var reader = new DirectiveMetadataReader();
|
||||
var cache = new CompilerCache();
|
||||
var compiler = new Compiler(null, reader, new Parser(new Lexer()), cache);
|
||||
var annotatedComponent = reader.annotatedType(BenchmarkComponent);
|
||||
|
||||
benchmark(`Compiler.compile 5*${COUNT} element no bindings`, function() {
|
||||
var template = loadTemplate('templateNoBindings', COUNT);
|
||||
var templateNoBindings = loadTemplate('templateNoBindings', COUNT);
|
||||
var templateWithBindings = loadTemplate('templateWithBindings', COUNT);
|
||||
|
||||
benchmarkStep('run', function() {
|
||||
// Need to clone every time as the compiler might modify the template!
|
||||
var cloned = DOM.clone(template);
|
||||
compiler.compileAllLoaded(null, annotatedComponent, cloned);
|
||||
});
|
||||
});
|
||||
function compileNoBindings(_) {
|
||||
// Need to clone every time as the compiler might modify the template!
|
||||
var cloned = DOM.clone(templateNoBindings);
|
||||
cache.clear();
|
||||
compiler.compileAllLoaded(null, annotatedComponent, cloned);
|
||||
}
|
||||
|
||||
benchmark(`Compiler.compile 5*${COUNT} element with bindings`, function() {
|
||||
var template = loadTemplate('templateWithBindings', COUNT);
|
||||
function compileWithBindings(_) {
|
||||
// Need to clone every time as the compiler might modify the template!
|
||||
var cloned = DOM.clone(templateWithBindings);
|
||||
cache.clear();
|
||||
compiler.compileAllLoaded(null, annotatedComponent, cloned);
|
||||
}
|
||||
|
||||
benchmarkStep('run', function() {
|
||||
// Need to clone every time as the compiler might modify the template!
|
||||
var cloned = DOM.clone(template);
|
||||
compiler.compileAllLoaded(null, annotatedComponent, cloned);
|
||||
});
|
||||
});
|
||||
|
||||
benchmark(`instantiate 5*${COUNT} element with bindings`, function() {
|
||||
var template = loadTemplate('templateWithBindings', COUNT);
|
||||
var protoView = compiler.compileWithCache(null, annotatedComponent, template);
|
||||
var rootRecordRange = new ProtoRecordRange().instantiate(null, null);
|
||||
|
||||
benchmarkStep('run', function() {
|
||||
var view = protoView.instantiate(null, null, null);
|
||||
// also include adding / removing the RecordRange from the parent in the benchmark.
|
||||
rootRecordRange.addRange(view.recordRange);
|
||||
view.recordRange.remove();
|
||||
});
|
||||
});
|
||||
DOM.on(DOM.querySelector(document, '#compileNoBindings'), 'click', compileNoBindings);
|
||||
DOM.on(DOM.querySelector(document, '#compileWithBindings'), 'click', compileWithBindings);
|
||||
}
|
||||
|
||||
function loadTemplate(templateId, repeatCount) {
|
||||
@ -132,22 +114,6 @@ function loadTemplate(templateId, repeatCount) {
|
||||
return DOM.createTemplate(result);
|
||||
}
|
||||
|
||||
// Caching reflector as reflection in Dart using Mirrors
|
||||
class CachingDirectiveMetadataReader extends DirectiveMetadataReader {
|
||||
_cache: Map;
|
||||
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({
|
||||
selector: '[dir0]',
|
||||
bind: {
|
||||
|
@ -1,7 +0,0 @@
|
||||
import * as sbm from './selector_benchmark';
|
||||
import * as cbm from './compiler_benchmark';
|
||||
|
||||
export function main() {
|
||||
sbm.main();
|
||||
cbm.main();
|
||||
}
|
12
modules/benchmarks/src/compiler/selector_benchmark.html
Normal file
12
modules/benchmarks/src/compiler/selector_benchmark.html
Normal file
@ -0,0 +1,12 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<button id="parse">Selector.parse</button>
|
||||
<button id="addSelectable">Selector.addSelectable</button>
|
||||
<button id="match">Selector.match</button>
|
||||
|
||||
$SCRIPTS$
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,63 +1,56 @@
|
||||
import {benchmark, benchmarkStep} from 'benchpress/benchpress';
|
||||
import {document, DOM} from 'facade/dom';
|
||||
|
||||
import {SelectorMatcher} from "core/compiler/selector";
|
||||
import {CssSelector} from "core/compiler/selector";
|
||||
import {StringWrapper, Math} from 'facade/lang';
|
||||
import {ListWrapper} from 'facade/collection';
|
||||
|
||||
var fixedMatcher;
|
||||
var fixedSelectorStrings = [];
|
||||
var fixedSelectors = [];
|
||||
|
||||
var COUNT = 1000;
|
||||
|
||||
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++) {
|
||||
var fixedMatcher;
|
||||
var fixedSelectorStrings = [];
|
||||
var fixedSelectors = [];
|
||||
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);
|
||||
}
|
||||
|
||||
function parse(_) {
|
||||
var result = [];
|
||||
for (var i=0; i<COUNT; i++) {
|
||||
ListWrapper.push(result, CssSelector.parse(fixedSelectorStrings[i]));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function addSelectable(_) {
|
||||
var matcher = new SelectorMatcher();
|
||||
for (var i=0; i<COUNT; i++) {
|
||||
matcher.addSelectable(fixedSelectors[i], i);
|
||||
}
|
||||
return matcher;
|
||||
}
|
||||
|
||||
function match(_) {
|
||||
var matchCount = 0;
|
||||
for (var i=0; i<COUNT; i++) {
|
||||
fixedMatcher.match(fixedSelectors[i], (selected) => {
|
||||
matchCount += selected;
|
||||
});
|
||||
}
|
||||
return matchCount;
|
||||
}
|
||||
|
||||
DOM.on(DOM.querySelector(document, '#parse'), 'click', parse);
|
||||
DOM.on(DOM.querySelector(document, '#addSelectable'), 'click', addSelectable);
|
||||
DOM.on(DOM.querySelector(document, '#match'), 'click', match);
|
||||
}
|
||||
|
||||
function randomSelector() {
|
||||
|
Reference in New Issue
Block a user