parent
9b7e2e3029
commit
01fa90c11d
|
@ -0,0 +1,3 @@
|
||||||
|
$SCRIPTS$
|
||||||
|
|
||||||
|
<app></app>
|
|
@ -0,0 +1,5 @@
|
||||||
|
import * as tree_benchmark from './tree_benchmark';
|
||||||
|
|
||||||
|
export function main() {
|
||||||
|
tree_benchmark.main();
|
||||||
|
}
|
|
@ -0,0 +1,198 @@
|
||||||
|
import {benchmark, benchmarkStep} from 'benchpress/benchpress';
|
||||||
|
|
||||||
|
import {ChangeDetector} from 'change_detection/change_detector';
|
||||||
|
import {Parser} from 'change_detection/parser/parser';
|
||||||
|
import {Lexer} from 'change_detection/parser/lexer';
|
||||||
|
|
||||||
|
import {bootstrap, Component, Template, TemplateConfig, ViewPort, Compiler} from 'core/core';
|
||||||
|
|
||||||
|
import {CompilerCache} from 'core/compiler/compiler';
|
||||||
|
import {DirectiveMetadataReader} from 'core/compiler/directive_metadata_reader';
|
||||||
|
import {TemplateLoader} from 'core/compiler/template_loader';
|
||||||
|
|
||||||
|
import {reflector} from 'reflection/reflection';
|
||||||
|
|
||||||
|
var MAX_DEPTH = 9;
|
||||||
|
|
||||||
|
function setup() {
|
||||||
|
// TODO: Put the general calls to reflector.register... in a shared file
|
||||||
|
// as they are needed in all benchmarks...
|
||||||
|
|
||||||
|
reflector.registerType(AppComponent, {
|
||||||
|
'factory': () => new AppComponent(),
|
||||||
|
'parameters': [],
|
||||||
|
'annotations' : [new Component({
|
||||||
|
selector: 'app',
|
||||||
|
template: new TemplateConfig({
|
||||||
|
directives: [TreeComponent],
|
||||||
|
inline: `<tree [data]='initData'></tree>`
|
||||||
|
})
|
||||||
|
})]
|
||||||
|
});
|
||||||
|
|
||||||
|
reflector.registerType(TreeComponent, {
|
||||||
|
'factory': () => new TreeComponent(),
|
||||||
|
'parameters': [],
|
||||||
|
'annotations' : [new Component({
|
||||||
|
selector: 'tree',
|
||||||
|
bind: {
|
||||||
|
'data': 'data'
|
||||||
|
},
|
||||||
|
template: new TemplateConfig({
|
||||||
|
directives: [TreeComponent, NgIf],
|
||||||
|
inline: `
|
||||||
|
<span> {{data.value}}
|
||||||
|
<span template='ng-if data.left != null'><tree [data]='data.left'></span>
|
||||||
|
<span template='ng-if data.right != null'><tree [data]='data.right'></span>
|
||||||
|
</span>`
|
||||||
|
})
|
||||||
|
})]
|
||||||
|
});
|
||||||
|
|
||||||
|
reflector.registerType(NgIf, {
|
||||||
|
'factory': (vp) => new NgIf(vp),
|
||||||
|
'parameters': [[ViewPort]],
|
||||||
|
'annotations' : [new Template({
|
||||||
|
selector: '[ng-if]',
|
||||||
|
bind: {
|
||||||
|
'ng-if': 'ngIf'
|
||||||
|
}
|
||||||
|
})]
|
||||||
|
});
|
||||||
|
|
||||||
|
reflector.registerType(Compiler, {
|
||||||
|
'factory': (templateLoader, reader, parser, compilerCache) => new Compiler(templateLoader, reader, parser, compilerCache),
|
||||||
|
'parameters': [[TemplateLoader], [DirectiveMetadataReader], [Parser], [CompilerCache]],
|
||||||
|
'annotations': []
|
||||||
|
});
|
||||||
|
|
||||||
|
reflector.registerType(CompilerCache, {
|
||||||
|
'factory': () => new CompilerCache(),
|
||||||
|
'parameters': [],
|
||||||
|
'annotations': []
|
||||||
|
});
|
||||||
|
|
||||||
|
reflector.registerType(Parser, {
|
||||||
|
'factory': (lexer) => new Parser(lexer),
|
||||||
|
'parameters': [[Lexer]],
|
||||||
|
'annotations': []
|
||||||
|
});
|
||||||
|
|
||||||
|
reflector.registerType(TemplateLoader, {
|
||||||
|
'factory': () => new TemplateLoader(),
|
||||||
|
'parameters': [],
|
||||||
|
'annotations': []
|
||||||
|
});
|
||||||
|
|
||||||
|
reflector.registerType(DirectiveMetadataReader, {
|
||||||
|
'factory': () => new DirectiveMetadataReader(),
|
||||||
|
'parameters': [],
|
||||||
|
'annotations': []
|
||||||
|
});
|
||||||
|
|
||||||
|
reflector.registerType(Lexer, {
|
||||||
|
'factory': () => new Lexer(),
|
||||||
|
'parameters': [],
|
||||||
|
'annotations': []
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
reflector.registerGetters({
|
||||||
|
'value': (a) => a.value,
|
||||||
|
'left': (a) => a.left,
|
||||||
|
'right': (a) => a.right,
|
||||||
|
'initData': (a) => a.initData,
|
||||||
|
'data': (a) => a.data
|
||||||
|
});
|
||||||
|
|
||||||
|
reflector.registerSetters({
|
||||||
|
'value': (a,v) => a.value = v,
|
||||||
|
'left': (a,v) => a.left = v,
|
||||||
|
'right': (a,v) => a.right = v,
|
||||||
|
'initData': (a,v) => a.initData = v,
|
||||||
|
'data': (a,v) => a.data = v,
|
||||||
|
'ngIf': (a,v) => a.ngIf = v
|
||||||
|
});
|
||||||
|
|
||||||
|
return bootstrap(AppComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function main() {
|
||||||
|
var app;
|
||||||
|
var changeDetector;
|
||||||
|
setup().then((injector) => {
|
||||||
|
changeDetector = injector.get(ChangeDetector);
|
||||||
|
app = injector.get(AppComponent);
|
||||||
|
});
|
||||||
|
|
||||||
|
benchmark(`tree benchmark`, function() {
|
||||||
|
var count = 0;
|
||||||
|
|
||||||
|
benchmarkStep(`destroyDom binary tree of depth ${MAX_DEPTH}`, function() {
|
||||||
|
// TODO: We need an initial value as otherwise the getter for data.value will fail
|
||||||
|
// --> this should be already caught in change detection!
|
||||||
|
app.initData = new TreeNode('', null, null);
|
||||||
|
changeDetector.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
benchmarkStep(`createDom binary tree of depth ${MAX_DEPTH}`, function() {
|
||||||
|
var maxDepth = 9;
|
||||||
|
var values = count++ % 2 == 0 ?
|
||||||
|
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*'] :
|
||||||
|
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', '-'];
|
||||||
|
|
||||||
|
app.initData = buildTree(maxDepth, values, 0);
|
||||||
|
changeDetector.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class TreeNode {
|
||||||
|
value:string;
|
||||||
|
left:TreeNode;
|
||||||
|
right:TreeNode;
|
||||||
|
constructor(value, left, right) {
|
||||||
|
this.value = value;
|
||||||
|
this.left = left;
|
||||||
|
this.right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildTree(maxDepth, values, curDepth) {
|
||||||
|
if (maxDepth === curDepth) return new TreeNode('', null, null);
|
||||||
|
return new TreeNode(
|
||||||
|
values[curDepth],
|
||||||
|
buildTree(maxDepth, values, curDepth+1),
|
||||||
|
buildTree(maxDepth, values, curDepth+1));
|
||||||
|
}
|
||||||
|
|
||||||
|
class AppComponent {
|
||||||
|
initData:TreeNode;
|
||||||
|
constructor() {
|
||||||
|
// TODO: We need an initial value as otherwise the getter for data.value will fail
|
||||||
|
// --> this should be already caught in change detection!
|
||||||
|
this.initData = new TreeNode('', null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Move this into a reusable directive in the 'core' module!
|
||||||
|
class NgIf {
|
||||||
|
_viewPort:ViewPort;
|
||||||
|
constructor(viewPort:ViewPort) {
|
||||||
|
this._viewPort = viewPort;
|
||||||
|
}
|
||||||
|
set ngIf(value:boolean) {
|
||||||
|
if (this._viewPort.length > 0) {
|
||||||
|
this._viewPort.remove(0);
|
||||||
|
}
|
||||||
|
if (value) {
|
||||||
|
this._viewPort.create();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TreeComponent {
|
||||||
|
data:TreeNode;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
library tree_benchmark;
|
||||||
|
|
||||||
|
import './tree_benchmark_ng10.dart' as bm;
|
||||||
|
|
||||||
|
main () {
|
||||||
|
bm.main();
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
export {main} from './tree_benchmark_ng13';
|
|
@ -0,0 +1,3 @@
|
||||||
|
$SCRIPTS$
|
||||||
|
|
||||||
|
<tree data="initData"></tree>
|
|
@ -0,0 +1,76 @@
|
||||||
|
library tree_benchmark_ng10;
|
||||||
|
|
||||||
|
import 'package:angular/angular.dart';
|
||||||
|
import 'package:angular/application_factory.dart';
|
||||||
|
import 'package:benchpress/benchpress.dart';
|
||||||
|
import 'dart:html';
|
||||||
|
|
||||||
|
var MAX_DEPTH = 9;
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
|
||||||
|
var m = new Module()
|
||||||
|
..bind(CompilerConfig, toValue: new CompilerConfig.withOptions(elementProbeEnabled: false))
|
||||||
|
..bind(ScopeDigestTTL, toFactory: () => new ScopeDigestTTL.value(15), inject: [])
|
||||||
|
..bind(TreeComponent);
|
||||||
|
|
||||||
|
final injector = applicationFactory().addModule(m).run();
|
||||||
|
|
||||||
|
return injector;
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
final injector = setup();
|
||||||
|
final zone = injector.get(VmTurnZone);
|
||||||
|
final rootScope = injector.get(Scope);
|
||||||
|
|
||||||
|
benchmark("tree benchmark", () {
|
||||||
|
var count = 0;
|
||||||
|
|
||||||
|
benchmarkStep("AngularDart destroyDom binary tree of depth ${MAX_DEPTH}", () {
|
||||||
|
zone.run(() {
|
||||||
|
rootScope.context['initData'] = new TreeNode('');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
benchmarkStep("AngularDart createDom binary tree of depth ${MAX_DEPTH}", () {
|
||||||
|
zone.run(() {
|
||||||
|
var maxDepth = 9;
|
||||||
|
var values = count++ % 2 == 0 ?
|
||||||
|
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*'] :
|
||||||
|
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', '-'];
|
||||||
|
|
||||||
|
rootScope.context['initData'] = buildTree(maxDepth, values, 0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component(
|
||||||
|
selector: 'tree',
|
||||||
|
map: const {'data': '=>data'},
|
||||||
|
template: '<span> {{data.value}}'
|
||||||
|
'<span ng-if="data.right != null"><tree data=data.right></span>'
|
||||||
|
'<span ng-if="data.left != null"><tree data=data.left></span>'
|
||||||
|
'</span>'
|
||||||
|
)
|
||||||
|
class TreeComponent {
|
||||||
|
var data;
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTree(maxDepth, values, curDepth) {
|
||||||
|
if (maxDepth == curDepth) return new TreeNode('');
|
||||||
|
return new TreeNode(
|
||||||
|
values[curDepth],
|
||||||
|
buildTree(maxDepth, values, curDepth+1),
|
||||||
|
buildTree(maxDepth, values, curDepth+1));
|
||||||
|
}
|
||||||
|
|
||||||
|
class TreeNode {
|
||||||
|
var value;
|
||||||
|
TreeNode left;
|
||||||
|
TreeNode right;
|
||||||
|
TreeNode([this.value, this.left, this.right]);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
import {benchmark, benchmarkStep} from 'benchpress/benchpress';
|
||||||
|
|
||||||
|
var MAX_DEPTH = 9;
|
||||||
|
|
||||||
|
function setup() {
|
||||||
|
var $rootScope;
|
||||||
|
|
||||||
|
angular.module('app', [])
|
||||||
|
.directive('tree', function() {
|
||||||
|
return {
|
||||||
|
scope: {
|
||||||
|
data: '='
|
||||||
|
},
|
||||||
|
template:
|
||||||
|
'<span> {{data.value}}'+
|
||||||
|
' <span tree-if="data.left"></span>'+
|
||||||
|
' <span tree-if="data.right"></span>'+
|
||||||
|
'</span>'
|
||||||
|
};
|
||||||
|
})
|
||||||
|
// special directive for "if" as angular 1.3 does not support
|
||||||
|
// recursive components.
|
||||||
|
.directive('treeIf', ['$compile', '$parse', function($compile, $parse) {
|
||||||
|
var transcludeFn;
|
||||||
|
return {
|
||||||
|
compile: function(element, attrs) {
|
||||||
|
var expr = $parse(attrs.treeIf);
|
||||||
|
var template = '<tree data="'+attrs.treeIf+'"></tree>';
|
||||||
|
var transclude;
|
||||||
|
return function($scope, $element, $attrs) {
|
||||||
|
if (!transclude) {
|
||||||
|
transclude = $compile(template);
|
||||||
|
}
|
||||||
|
var childScope;
|
||||||
|
var childElement;
|
||||||
|
$scope.$watch(expr, function(newValue) {
|
||||||
|
if (childScope) {
|
||||||
|
childScope.$destroy();
|
||||||
|
childElement.remove();
|
||||||
|
childScope = null;
|
||||||
|
childElement = null;
|
||||||
|
}
|
||||||
|
if (newValue) {
|
||||||
|
childScope = $scope.$new();
|
||||||
|
childElement = transclude(childScope, function(clone) {
|
||||||
|
$element.append(clone);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}])
|
||||||
|
.config(['$compileProvider', function($compileProvider) {
|
||||||
|
$compileProvider.debugInfoEnabled(false);
|
||||||
|
}])
|
||||||
|
.run(['$rootScope', function(_$rootScope_) {
|
||||||
|
$rootScope = _$rootScope_;
|
||||||
|
}])
|
||||||
|
angular.bootstrap(document.body, ['app']);
|
||||||
|
return $rootScope;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function main() {
|
||||||
|
var $rootScope = setup();
|
||||||
|
|
||||||
|
benchmark(`tree benchmark`, function() {
|
||||||
|
var count = 0;
|
||||||
|
|
||||||
|
benchmarkStep(`AngularJS destroyDom binary tree of depth ${MAX_DEPTH}`, function() {
|
||||||
|
$rootScope.$apply(function() {
|
||||||
|
$rootScope.initData = new TreeNode('', null, null);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
benchmarkStep(`AngularJS createDom binary tree of depth ${MAX_DEPTH}`, function() {
|
||||||
|
var maxDepth = 9;
|
||||||
|
var values = count++ % 2 == 0 ?
|
||||||
|
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*'] :
|
||||||
|
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', '-'];
|
||||||
|
|
||||||
|
$rootScope.$apply(function() {
|
||||||
|
$rootScope.initData = buildTree(maxDepth, values, 0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class TreeNode {
|
||||||
|
value:string;
|
||||||
|
left:TreeNode;
|
||||||
|
right:TreeNode;
|
||||||
|
constructor(value, left, right) {
|
||||||
|
this.value = value;
|
||||||
|
this.left = left;
|
||||||
|
this.right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildTree(maxDepth, values, curDepth) {
|
||||||
|
if (maxDepth === curDepth) return new TreeNode('', null, null);
|
||||||
|
return new TreeNode(
|
||||||
|
values[curDepth],
|
||||||
|
buildTree(maxDepth, values, curDepth+1),
|
||||||
|
buildTree(maxDepth, values, curDepth+1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue