parent
11f7e275e6
commit
446b51e164
|
@ -1,6 +0,0 @@
|
|||
# How to run the benchmarks_external locally
|
||||
|
||||
$ cp -r ./modules/benchmarks_external ./dist/all/
|
||||
$ ./node_modules/.bin/tsc -p modules --emitDecoratorMetadata -w
|
||||
$ gulp serve
|
||||
$ open http://localhost:8000/all/benchmarks_external/src/tree/index.html?bundles=false
|
|
@ -1,37 +0,0 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {runClickBenchmark, verifyNoBrowserErrors} from '@angular/testing/src/perf_util';
|
||||
|
||||
describe('ng1.x compiler benchmark', function() {
|
||||
|
||||
const URL = 'benchmarks_external/src/compiler/compiler_benchmark.html';
|
||||
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
it('should log withBinding stats', function(done) {
|
||||
runClickBenchmark({
|
||||
url: URL,
|
||||
buttons: ['#compileWithBindings'],
|
||||
id: 'ng1.compile.withBindings',
|
||||
params: [{name: 'elements', value: 150, scale: 'linear'}],
|
||||
waitForAngular2: false
|
||||
}).then(done, done.fail);
|
||||
});
|
||||
|
||||
it('should log noBindings stats', function(done) {
|
||||
runClickBenchmark({
|
||||
url: URL,
|
||||
buttons: ['#compileNoBindings'],
|
||||
id: 'ng1.compile.noBindings',
|
||||
params: [{name: 'elements', value: 150, scale: 'linear'}],
|
||||
waitForAngular2: false
|
||||
}).then(done, done.fail);
|
||||
});
|
||||
|
||||
});
|
|
@ -1,33 +0,0 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {runClickBenchmark, verifyNoBrowserErrors} from '@angular/testing/src/perf_util';
|
||||
|
||||
describe('ng1.x largetable benchmark', function() {
|
||||
const URL = 'benchmarks_external/src/largetable/largetable_benchmark.html';
|
||||
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
['baselineBinding', 'baselineInterpolation', 'ngBind', 'ngBindOnce', 'interpolation',
|
||||
'interpolationAttr', 'ngBindFn', 'interpolationFn', 'ngBindFilter', 'interpolationFilter']
|
||||
.forEach(function(benchmarkType) {
|
||||
it('should log the stats with: ' + benchmarkType, function(done) {
|
||||
runClickBenchmark({
|
||||
url: URL,
|
||||
buttons: ['#destroyDom', '#createDom'],
|
||||
id: 'ng1.largetable.' + benchmarkType,
|
||||
params: [
|
||||
{name: 'columns', value: 100, scale: 'sqrt'},
|
||||
{name: 'rows', value: 20, scale: 'sqrt'},
|
||||
{name: 'benchmarkType', value: benchmarkType}
|
||||
],
|
||||
waitForAngular2: false
|
||||
}).then(done, done.fail);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,41 +0,0 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {runBenchmark, verifyNoBrowserErrors} from '@angular/testing/src/perf_util';
|
||||
|
||||
describe('ng-dart1.x naive infinite scroll benchmark', function() {
|
||||
|
||||
const URL = 'benchmarks_external/src/naive_infinite_scroll/index.html';
|
||||
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
[1, 2, 4].forEach(function(appSize) {
|
||||
it('should run scroll benchmark and collect stats for appSize = ' + appSize, function(done) {
|
||||
runBenchmark({
|
||||
url: URL,
|
||||
id: 'ng1-dart1.x.naive_infinite_scroll',
|
||||
work: function() {
|
||||
$('#reset-btn').click();
|
||||
$('#run-btn').click();
|
||||
let s = 1000;
|
||||
if (appSize > 4) {
|
||||
s = s + appSize * 100;
|
||||
}
|
||||
browser.sleep(s);
|
||||
},
|
||||
params: [
|
||||
{name: 'appSize', value: appSize},
|
||||
{name: 'iterationCount', value: 20, scale: 'linear'},
|
||||
{name: 'scrollIncrement', value: 40}
|
||||
],
|
||||
waitForAngular2: false
|
||||
}).then(done, done.fail);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
|
@ -1,37 +0,0 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {runClickBenchmark, verifyNoBrowserErrors} from '@angular/testing/src/perf_util';
|
||||
|
||||
describe('react tree benchmark', function() {
|
||||
|
||||
const URL = 'benchmarks_external/src/tree/react/index.html';
|
||||
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
it('should log the stats (create)', function(done) {
|
||||
runClickBenchmark({
|
||||
url: URL,
|
||||
buttons: ['#destroyDom', '#createDom'],
|
||||
id: 'react.tree.create',
|
||||
params: [{name: 'depth', value: 9, scale: 'log2'}],
|
||||
waitForAngular2: false
|
||||
}).then(done, done.fail);
|
||||
});
|
||||
|
||||
it('should log the stats (update)', function(done) {
|
||||
runClickBenchmark({
|
||||
url: URL,
|
||||
buttons: ['#createDom'],
|
||||
id: 'react.tree.update',
|
||||
params: [{name: 'depth', value: 9, scale: 'log2'}],
|
||||
waitForAngular2: false
|
||||
}).then(done, done.fail);
|
||||
});
|
||||
|
||||
});
|
|
@ -1,37 +0,0 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {runClickBenchmark, verifyNoBrowserErrors} from '@angular/testing/src/perf_util';
|
||||
|
||||
describe('ng1.x tree benchmark', function() {
|
||||
|
||||
const URL = 'benchmarks_external/src/static_tree/tree_benchmark.html';
|
||||
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
it('should log the stats (create)', function(done) {
|
||||
runClickBenchmark({
|
||||
url: URL,
|
||||
buttons: ['#destroyDom', '#createDom'],
|
||||
id: 'ng1.static.tree.create',
|
||||
params: [],
|
||||
waitForAngular2: false
|
||||
}).then(done, done.fail);
|
||||
});
|
||||
|
||||
it('should log the stats (update)', function(done) {
|
||||
runClickBenchmark({
|
||||
url: URL,
|
||||
buttons: ['#createDom'],
|
||||
id: 'ng1.static.tree.update',
|
||||
params: [],
|
||||
waitForAngular2: false
|
||||
}).then(done, done.fail);
|
||||
});
|
||||
|
||||
});
|
|
@ -1,37 +0,0 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {runClickBenchmark, verifyNoBrowserErrors} from '@angular/testing/src/perf_util';
|
||||
|
||||
describe('ng1.x tree benchmark', function() {
|
||||
|
||||
const URL = 'benchmarks_external/src/tree/tree_benchmark.html';
|
||||
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
it('should log the stats (create)', function(done) {
|
||||
runClickBenchmark({
|
||||
url: URL,
|
||||
buttons: ['#destroyDom', '#createDom'],
|
||||
id: 'ng1.tree.create',
|
||||
params: [{name: 'depth', value: 9, scale: 'log2'}],
|
||||
waitForAngular2: false
|
||||
}).then(done, done.fail);
|
||||
});
|
||||
|
||||
it('should log the stats (update)', function(done) {
|
||||
runClickBenchmark({
|
||||
url: URL,
|
||||
buttons: ['#createDom'],
|
||||
id: 'ng1.tree.update',
|
||||
params: [{name: 'depth', value: 9, scale: 'log2'}],
|
||||
waitForAngular2: false
|
||||
}).then(done, done.fail);
|
||||
});
|
||||
|
||||
});
|
|
@ -1,91 +0,0 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
|
||||
(function(global: any /** TODO #9100 */) {
|
||||
|
||||
writeScriptTag('/all/benchmarks/vendor/core.js');
|
||||
writeScriptTag('/all/benchmarks/vendor/zone.js');
|
||||
writeScriptTag('/all/benchmarks/vendor/long-stack-trace-zone.js');
|
||||
writeScriptTag('/all/benchmarks/vendor/system.src.js');
|
||||
writeScriptTag('/all/benchmarks/vendor/Reflect.js', 'benchmarksBootstrap()');
|
||||
|
||||
(<any>global).benchmarksBootstrap = benchmarksBootstrap;
|
||||
|
||||
function benchmarksBootstrap() {
|
||||
// check query param
|
||||
const useBundles = location.search.indexOf('bundles=false') == -1;
|
||||
if (useBundles) {
|
||||
System.config({
|
||||
map: {
|
||||
'index': 'index.js',
|
||||
'@angular/core': '/packages-dist/core/bundles/core.umd.js',
|
||||
'@angular/common': '/packages-dist/common/bundles/common.umd.js',
|
||||
'@angular/forms': '/packages-dist/forms/bundles/forms.umd.js',
|
||||
'@angular/compiler': '/packages-dist/compiler/bundles/compiler.umd.js',
|
||||
'@angular/platform-browser':
|
||||
'/packages-dist/platform-browser/bundles/platform-browser.umd.js',
|
||||
'@angular/platform-browser-dynamic':
|
||||
'/packages-dist/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
|
||||
'@angular/http': '/packages-dist/http/bundles/http.umd.js',
|
||||
'@angular/upgrade': '/packages-dist/upgrade/bundles/upgrade.umd.js',
|
||||
'@angular/router': '/packages-dist/router/bundles/router.umd.js',
|
||||
'@angular/core/src/facade': '/all/@angular/core/src/facade',
|
||||
'rxjs': 'node_modules/rxjs',
|
||||
},
|
||||
packages: {
|
||||
'app': {defaultExtension: 'js'},
|
||||
'@angular/core/src/facade': {defaultExtension: 'js'},
|
||||
'rxjs/ajax': {main: 'index.js', defaultExtension: 'js' },
|
||||
'rxjs/operators': {main: 'index.js', defaultExtension: 'js' },
|
||||
'rxjs/testing': {main: 'index.js', defaultExtension: 'js' },
|
||||
'rxjs/websocket': {main: 'index.js', defaultExtension: 'js' },
|
||||
'rxjs': { main: 'index.js', defaultExtension: 'js' },
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.warn(
|
||||
'Not using the Angular bundles. Don\'t use this configuration for e2e/performance tests!');
|
||||
|
||||
System.config({
|
||||
map: {
|
||||
'index': 'index.js',
|
||||
'@angular': '/all/@angular',
|
||||
'rxjs': 'node_modules/rxjs',
|
||||
},
|
||||
packages: {
|
||||
'app': {defaultExtension: 'js'},
|
||||
'@angular/core': {main: 'index.js', defaultExtension: 'js'},
|
||||
'@angular/compiler': {main: 'index.js', defaultExtension: 'js'},
|
||||
'@angular/router': {main: 'index.js', defaultExtension: 'js'},
|
||||
'@angular/common': {main: 'index.js', defaultExtension: 'js'},
|
||||
'@angular/forms': {main: 'index.js', defaultExtension: 'js'},
|
||||
'@angular/platform-browser': {main: 'index.js', defaultExtension: 'js'},
|
||||
'@angular/platform-browser-dynamic': {main: 'index.js', defaultExtension: 'js'},
|
||||
'@angular/upgrade': {main: 'index.js', defaultExtension: 'js'},
|
||||
'rxjs/ajax': {main: 'index.js', defaultExtension: 'js' },
|
||||
'rxjs/operators': {main: 'index.js', defaultExtension: 'js' },
|
||||
'rxjs/testing': {main: 'index.js', defaultExtension: 'js' },
|
||||
'rxjs/websocket': {main: 'index.js', defaultExtension: 'js' },
|
||||
'rxjs': { main: 'index.js', defaultExtension: 'js' },
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// BOOTSTRAP the app!
|
||||
System.import('index').then(function(m: any /** TODO #9100 */) {
|
||||
m.main();
|
||||
}, console.error.bind(console));
|
||||
}
|
||||
|
||||
|
||||
function writeScriptTag(scriptUrl: any /** TODO #9100 */, onload?: any /** TODO #9100 */) {
|
||||
document.write(`<script src="${scriptUrl}" onload="${onload}"></script>`);
|
||||
}
|
||||
}(window));
|
|
@ -1,53 +0,0 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<h2>Params</h2>
|
||||
<form>
|
||||
Elements:
|
||||
<input type="number" name="elements" placeholder="elements" value="150">
|
||||
<br>
|
||||
<button>Apply</button>
|
||||
</form>
|
||||
|
||||
<h2>Actions</h2>
|
||||
<p>
|
||||
<button id="compileWithBindings">CompileWithBindings</button>
|
||||
<button id="compileNoBindings">CompileNoBindings</button>
|
||||
</p>
|
||||
|
||||
<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>
|
||||
|
||||
$SCRIPTS$
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,117 +0,0 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
// compiler benchmark in AngularJS 1.x
|
||||
import {getIntParameter, bindAction} from '@angular/testing/src/benchmark_util';
|
||||
declare var angular: any;
|
||||
|
||||
export function main() {
|
||||
const ngEl = document.createElement('div');
|
||||
angular.bootstrap(ngEl, ['app']);
|
||||
}
|
||||
|
||||
function loadTemplate(templateId, repeatCount) {
|
||||
const template = document.querySelectorAll(`#${templateId}`)[0];
|
||||
const content = (<HTMLElement>template).innerHTML;
|
||||
let result = '';
|
||||
for (let 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...
|
||||
const div = document.createElement('div');
|
||||
div.innerHTML = result;
|
||||
return div;
|
||||
}
|
||||
|
||||
angular.module('app', [])
|
||||
.directive('dir0',
|
||||
[
|
||||
'$parse',
|
||||
function($parse) {
|
||||
return {
|
||||
compile: function($element, $attrs) {
|
||||
const expr = $parse($attrs.attr0);
|
||||
return ($scope) => $scope.$watch(expr, angular.noop);
|
||||
}
|
||||
};
|
||||
}
|
||||
])
|
||||
.directive('dir1',
|
||||
[
|
||||
'$parse',
|
||||
function($parse) {
|
||||
return {
|
||||
compile: function($element, $attrs) {
|
||||
const expr = $parse($attrs.attr1);
|
||||
return ($scope) => $scope.$watch(expr, angular.noop);
|
||||
}
|
||||
};
|
||||
}
|
||||
])
|
||||
.directive('dir2',
|
||||
[
|
||||
'$parse',
|
||||
function($parse) {
|
||||
return {
|
||||
compile: function($element, $attrs) {
|
||||
const expr = $parse($attrs.attr2);
|
||||
return ($scope) => $scope.$watch(expr, angular.noop);
|
||||
}
|
||||
};
|
||||
}
|
||||
])
|
||||
.directive('dir3',
|
||||
[
|
||||
'$parse',
|
||||
function($parse) {
|
||||
return {
|
||||
compile: function($element, $attrs) {
|
||||
const expr = $parse($attrs.attr3);
|
||||
return ($scope) => $scope.$watch(expr, angular.noop);
|
||||
}
|
||||
};
|
||||
}
|
||||
])
|
||||
.directive('dir4',
|
||||
[
|
||||
'$parse',
|
||||
function($parse) {
|
||||
return {
|
||||
compile: function($element, $attrs) {
|
||||
const expr = $parse($attrs.attr4);
|
||||
return ($scope) => $scope.$watch(expr, angular.noop);
|
||||
}
|
||||
};
|
||||
}
|
||||
])
|
||||
.run([
|
||||
'$compile',
|
||||
function($compile) {
|
||||
const count = getIntParameter('elements');
|
||||
const templateNoBindings = loadTemplate('templateNoBindings', count);
|
||||
const templateWithBindings = loadTemplate('templateWithBindings', count);
|
||||
|
||||
bindAction('#compileWithBindings', compileWithBindings);
|
||||
bindAction('#compileNoBindings', compileNoBindings);
|
||||
|
||||
function compileNoBindings() {
|
||||
// Need to clone every time as the compiler might modify the template!
|
||||
const cloned = templateNoBindings.cloneNode(true);
|
||||
$compile(cloned);
|
||||
}
|
||||
|
||||
function compileWithBindings() {
|
||||
// Need to clone every time as the compiler might modify the template!
|
||||
const cloned = templateWithBindings.cloneNode(true);
|
||||
$compile(cloned);
|
||||
}
|
||||
}
|
||||
]);
|
|
@ -1,26 +0,0 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<body>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="compiler/compiler_benchmark.html">Compiler benchmark</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="tree/tree_benchmark.html">Tree benchmark</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="static_tree/tree_benchmark.html">Static tree benchmark</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="tree/react/index.html">React Tree benchmark</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="largetable/largetable_benchmark.html">Largetable benchmark</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="naive_infinite_scroll/index.html">Naive infinite scroll benchmark</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,58 +0,0 @@
|
|||
<ng-switch on="benchmarkType">
|
||||
<baseline-binding-table ng-switch-when="baselineBinding">
|
||||
</baseline-binding-table>
|
||||
<baseline-interpolation-table ng-switch-when="baselineInterpolation">
|
||||
</baseline-interpolation-table>
|
||||
<div ng-switch-when="ngBind">
|
||||
<h2>baseline binding</h2>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row">
|
||||
<span ng-bind="column.i"></span>:<span ng-bind="column.j"></span>|
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="ngBindOnce">
|
||||
<h2>baseline binding once</h2>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in ::row">
|
||||
<span ng-bind="::column.i"></span>:<span ng-bind="::column.j"></span>|
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="interpolation">
|
||||
<h2>baseline interpolation</h2>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row">{{column.i}}:{{column.j}}|</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="interpolationAttr">
|
||||
<h2>attribute interpolation</h2>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row" i="{{column.i}}" j="{{column.j}}">i,j attrs</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="ngBindFn">
|
||||
<h2>bindings with functions</h2>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row"><span ng-bind="column.iFn()"></span>:<span ng-bind="column.jFn()"></span>|</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="interpolationFn">
|
||||
<h2>interpolation with functions</h2>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row">{{column.iFn()}}:{{column.jFn()}}|</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="ngBindFilter">
|
||||
<h2>bindings with filter</h2>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row"><span ng-bind="column.i | noop"></span>:<span ng-bind="column.j | noop"></span>|</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="interpolationFilter">
|
||||
<h2>interpolation with filter</h2>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row">{{column.i | noop}}:{{column.j | noop}}|</span>
|
||||
</div>
|
||||
</div>
|
||||
</ng-switch>
|
|
@ -1,98 +0,0 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<h2>AngularJS/Dart 1.x largetable benchmark</h2>
|
||||
<form>
|
||||
<div>
|
||||
rows:
|
||||
<input type="number" name="rows" value="100">
|
||||
columns:
|
||||
<input type="number" name="columns" value="20">
|
||||
</div>
|
||||
<div>
|
||||
baseline binding:
|
||||
<input type="radio"
|
||||
name="benchmarkType"
|
||||
value="baselineBinding"
|
||||
id="baselineBinding"
|
||||
checked>
|
||||
</div>
|
||||
<div>
|
||||
baseline interpolation:
|
||||
<input type="radio"
|
||||
name="benchmarkType"
|
||||
value="baselineInterpolation"
|
||||
id="baselineInterpolation">
|
||||
</div>
|
||||
<div>
|
||||
ngBind:
|
||||
<input type="radio"
|
||||
name="benchmarkType"
|
||||
value="ngBind"
|
||||
id="ngBind">
|
||||
</div>
|
||||
<div>
|
||||
ngBindOnce:
|
||||
<input type="radio"
|
||||
name="benchmarkType"
|
||||
value="ngBindOnce"
|
||||
id="ngBindOnce">
|
||||
</div>
|
||||
<div>
|
||||
interpolation:
|
||||
<input type="radio"
|
||||
name="benchmarkType"
|
||||
value="interpolation"
|
||||
id="interpolation">
|
||||
</div>
|
||||
<div>
|
||||
attribute interpolation:
|
||||
<input type="radio"
|
||||
name="benchmarkType"
|
||||
value="interpolationAttr"
|
||||
id="interpolationAttr">
|
||||
</div>
|
||||
<div>
|
||||
ngBind + fnInvocation:
|
||||
<input type="radio"
|
||||
name="benchmarkType"
|
||||
value="ngBindFn"
|
||||
id="ngBindFn">
|
||||
</div>
|
||||
<div>
|
||||
interpolation + fnInvocation:
|
||||
<input type="radio"
|
||||
name="benchmarkType"
|
||||
value="interpolationFn"
|
||||
id="interpolationFn">
|
||||
</div>
|
||||
<div>
|
||||
ngBind + filter:
|
||||
<input type="radio"
|
||||
name="benchmarkType"
|
||||
value="ngBindFilter"
|
||||
id="ngBindFilter">
|
||||
</div>
|
||||
<div>
|
||||
interpolation + filter:
|
||||
<input type="radio"
|
||||
name="benchmarkType"
|
||||
value="interpolationFilter"
|
||||
id="interpolationFilter">
|
||||
</div>
|
||||
<button>Apply</button>
|
||||
</form>
|
||||
|
||||
<p>
|
||||
<button id="destroyDom">destroyDom</button>
|
||||
<button id="createDom">createDom</button>
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<largetable></largetable>
|
||||
</div>
|
||||
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
|
@ -1,119 +0,0 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {getIntParameter, getStringParameter, bindAction} from '@angular/testing/src/benchmark_util';
|
||||
declare var angular: any;
|
||||
|
||||
const totalRows = getIntParameter('rows');
|
||||
const totalColumns = getIntParameter('columns');
|
||||
const benchmarkType = getStringParameter('benchmarkType');
|
||||
|
||||
export function main() {
|
||||
angular.bootstrap(document.querySelector('largetable'), ['app']);
|
||||
}
|
||||
|
||||
angular.module('app', [])
|
||||
.config(function($compileProvider) {
|
||||
if ($compileProvider.debugInfoEnabled) {
|
||||
$compileProvider.debugInfoEnabled(false);
|
||||
}
|
||||
})
|
||||
.filter('noop', function() { return function(input) { return input; }; })
|
||||
.directive('largetable',
|
||||
function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
templateUrl: 'largetable-js-template.html',
|
||||
controller: 'DataController'
|
||||
};
|
||||
})
|
||||
.controller('DataController',
|
||||
function($scope) {
|
||||
bindAction('#destroyDom', destroyDom);
|
||||
bindAction('#createDom', createDom);
|
||||
|
||||
function destroyDom() {
|
||||
$scope.$apply(function() { $scope.benchmarkType = 'none'; });
|
||||
}
|
||||
|
||||
function createDom() {
|
||||
$scope.$apply(function() { $scope.benchmarkType = benchmarkType; });
|
||||
}
|
||||
|
||||
const data = $scope.data = [];
|
||||
|
||||
function iGetter() { return this.i; }
|
||||
function jGetter() { return this.j; }
|
||||
|
||||
for (let i = 0; i < totalRows; i++) {
|
||||
data[i] = [];
|
||||
for (let j = 0; j < totalColumns; j++) {
|
||||
data[i][j] = {i: i, j: j, iFn: iGetter, jFn: jGetter};
|
||||
}
|
||||
}
|
||||
})
|
||||
.directive('baselineBindingTable',
|
||||
function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function($scope, $element) {
|
||||
let i, j, row, cell, comment;
|
||||
const template = document.createElement('span');
|
||||
template.setAttribute('ng-repeat', 'foo in foos');
|
||||
template.classList.add('ng-scope');
|
||||
template.appendChild(document.createElement('span'));
|
||||
template.appendChild(document.createTextNode(':'));
|
||||
template.appendChild(document.createElement('span'));
|
||||
template.appendChild(document.createTextNode('|'));
|
||||
|
||||
for (i = 0; i < totalRows; i++) {
|
||||
row = document.createElement('div');
|
||||
$element[0].appendChild(row);
|
||||
for (j = 0; j < totalColumns; j++) {
|
||||
cell = template.cloneNode(true);
|
||||
row.appendChild(cell);
|
||||
cell.childNodes[0].textContent = i;
|
||||
cell.childNodes[2].textContent = j;
|
||||
cell.ng3992 = 'xxx';
|
||||
comment = document.createComment('ngRepeat end: bar in foo');
|
||||
row.appendChild(comment);
|
||||
}
|
||||
|
||||
comment = document.createComment('ngRepeat end: foo in foos');
|
||||
$element[0].appendChild(comment);
|
||||
}
|
||||
}
|
||||
};
|
||||
})
|
||||
.directive('baselineInterpolationTable', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function($scope, $element) {
|
||||
let i, j, row, cell, comment;
|
||||
const template = document.createElement('span');
|
||||
template.setAttribute('ng-repeat', 'foo in foos');
|
||||
template.classList.add('ng-scope');
|
||||
|
||||
for (i = 0; i < totalRows; i++) {
|
||||
row = document.createElement('div');
|
||||
$element[0].appendChild(row);
|
||||
for (j = 0; j < totalColumns; j++) {
|
||||
cell = template.cloneNode(true);
|
||||
row.appendChild(cell);
|
||||
cell.textContent = '' + i + ':' + j + '|';
|
||||
cell.ng3992 = 'xxx';
|
||||
comment = document.createComment('ngRepeat end: bar in foo');
|
||||
row.appendChild(comment);
|
||||
}
|
||||
|
||||
comment = document.createComment('ngRepeat end: foo in foos');
|
||||
$element[0].appendChild(comment);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
|
@ -1,20 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>AngularDart Scrolling Benchmark</title>
|
||||
</head>
|
||||
<body>
|
||||
<form>
|
||||
App size: <input type="text" name="appSize" value="1"><br>
|
||||
Iteration count: <input type="text" name="iterationCount" value="1"><br>
|
||||
Scroll increment: <input type="text" name="scrollIncrement" value="1"><br>
|
||||
</form>
|
||||
<div>
|
||||
<button id="run-btn">Run</button>
|
||||
<button id="reset-btn">Reset</button>
|
||||
</div>
|
||||
<scroll-app></scroll-app>
|
||||
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
|
@ -1,13 +0,0 @@
|
|||
<div>
|
||||
<div id="scrollDiv"
|
||||
ng-style="scrollDivStyle"
|
||||
ng-scroll="onScroll()">
|
||||
<div ng-style="paddingStyle"></div>
|
||||
<div ng-style="innerStyle">
|
||||
<scroll-item
|
||||
ng-repeat="item in visibleItems"
|
||||
offering="item">
|
||||
</scroll-item>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,45 +0,0 @@
|
|||
<div ng-style="itemStyle">
|
||||
<company-name company="offering.company"
|
||||
cell-width="companyNameWidth">
|
||||
</company-name>
|
||||
|
||||
<opportunity-name opportunity="offering.opportunity"
|
||||
cell-width="opportunityNameWidth">
|
||||
</opportunity-name>
|
||||
|
||||
<offering-name offering="offering"
|
||||
cell-width="offeringNameWidth">
|
||||
</offering-name>
|
||||
|
||||
<account-cell account="offering.account"
|
||||
cell-width="accountCellWidth">
|
||||
</account-cell>
|
||||
|
||||
<formatted-cell value="offering.basePoints"
|
||||
cell-width="basePointsWidth">
|
||||
</formatted-cell>
|
||||
|
||||
<formatted-cell value="offering.kickerPoints"
|
||||
cell-width="kickerPointsWidth">
|
||||
</formatted-cell>
|
||||
|
||||
<stage-buttons offering="offering"
|
||||
cell-width="stageButtonsWidth">
|
||||
</stage-buttons>
|
||||
|
||||
<formatted-cell value="offering.bundles"
|
||||
cell-width="bundlesWidth">
|
||||
</formatted-cell>
|
||||
|
||||
<formatted-cell value="offering.dueDate"
|
||||
cell-width="dueDateWidth">
|
||||
</formatted-cell>
|
||||
|
||||
<formatted-cell value="offering.endDate"
|
||||
cell-width="endDateWidth">
|
||||
</formatted-cell>
|
||||
|
||||
<formatted-cell value="offering.aatStatus"
|
||||
cell-width="aatStatusWidth">
|
||||
</formatted-cell>
|
||||
</div>
|
|
@ -1,17 +0,0 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<h2>AngularJS/Dart 1.x static tree benchmark (depth 10)</h2>
|
||||
<p>
|
||||
<button id="destroyDom">destroyDom</button>
|
||||
<button id="createDom">createDom</button>
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<tree9 data="initData" ng-if="initData != null" class="app"></tree9>
|
||||
</div>
|
||||
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
|
@ -1,77 +0,0 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
// static tree benchmark in AngularJS 1.x
|
||||
import {getIntParameter, bindAction} from '@angular/testing/src/benchmark_util';
|
||||
declare var angular: any;
|
||||
|
||||
const MAX_DEPTH = 10;
|
||||
|
||||
export function main() {
|
||||
angular.bootstrap(document.querySelector('.app'), ['app']);
|
||||
}
|
||||
|
||||
function addTreeDirective(module, level: number) {
|
||||
let template;
|
||||
if (level <= 0) {
|
||||
template = `<span> {{data.value}}</span>`;
|
||||
} else {
|
||||
template = `<span> {{data.value}} <tree${level-1} data='data.right'></tree${level-1}><tree${level-1} data='data.left'></tree${level-1}></span>`;
|
||||
}
|
||||
module.directive(`tree${level}`, function() { return {scope: {data: '='}, template: template}; });
|
||||
}
|
||||
|
||||
const module = angular.module('app', []);
|
||||
for (let depth = 0; depth < MAX_DEPTH; depth++) {
|
||||
addTreeDirective(module, depth);
|
||||
}
|
||||
module.config([
|
||||
'$compileProvider',
|
||||
function($compileProvider) { $compileProvider.debugInfoEnabled(false); }
|
||||
])
|
||||
.run([
|
||||
'$rootScope',
|
||||
function($rootScope) {
|
||||
let count = 0;
|
||||
$rootScope.initData = null;
|
||||
|
||||
bindAction('#destroyDom', destroyDom);
|
||||
bindAction('#createDom', createDom);
|
||||
|
||||
function createData(): TreeNode {
|
||||
const values = count++ % 2 == 0 ? ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*'] :
|
||||
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', '-'];
|
||||
return buildTree(MAX_DEPTH, values, 0);
|
||||
}
|
||||
|
||||
function destroyDom() {
|
||||
$rootScope.$apply(function() { $rootScope.initData = null; });
|
||||
}
|
||||
|
||||
function createDom() {
|
||||
$rootScope.$apply(function() { $rootScope.initData = createData(); });
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
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));
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>Params</h2>
|
||||
<form>
|
||||
Depth:
|
||||
<input type="number" name="depth" placeholder="depth" value="9">
|
||||
<br>
|
||||
<button>Apply</button>
|
||||
</form>
|
||||
<button id="destroyDom">destroyDom</button>
|
||||
<button id="createDom">createDom</button>
|
||||
|
||||
<h2>React Tree Benchmark</h2>
|
||||
<root-tree id="rootTree"></root-tree>
|
||||
|
||||
$SCRIPTS$
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,73 +0,0 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
// tree benchmark in React
|
||||
import {getIntParameter, bindAction} from '@angular/testing/src/benchmark_util';
|
||||
import * as React from './react.min';
|
||||
|
||||
const TreeComponent = React.createClass({
|
||||
displayName: 'TreeComponent',
|
||||
|
||||
render: function() {
|
||||
const treeNode = this.props.treeNode;
|
||||
|
||||
let left = null;
|
||||
if (treeNode.left) {
|
||||
left = React.createElement(
|
||||
"span", {}, [React.createElement(TreeComponent, {treeNode: treeNode.left}, "")]);
|
||||
}
|
||||
|
||||
let right = null;
|
||||
if (treeNode.right) {
|
||||
right = React.createElement(
|
||||
"span", {}, [React.createElement(TreeComponent, {treeNode: treeNode.right}, "")]);
|
||||
}
|
||||
|
||||
const span = React.createElement("span", {}, [" " + treeNode.value, left, right]);
|
||||
|
||||
return (React.createElement("tree", {}, [span]));
|
||||
}
|
||||
});
|
||||
|
||||
export function main() {
|
||||
let count = 0;
|
||||
const maxDepth = getIntParameter('depth');
|
||||
|
||||
bindAction('#destroyDom', destroyDom);
|
||||
bindAction('#createDom', createDom);
|
||||
|
||||
const empty = new TreeNode(0, null, null);
|
||||
const rootComponent = React.render(React.createElement(TreeComponent, {treeNode: empty}, ""),
|
||||
document.getElementById('rootTree'));
|
||||
|
||||
function destroyDom() { rootComponent.setProps({treeNode: empty}); }
|
||||
|
||||
function createDom() {
|
||||
const values = count++ % 2 == 0 ? ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*'] :
|
||||
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', '-'];
|
||||
rootComponent.setProps({treeNode: 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));
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
export var createElement: Function;
|
||||
export var render: Function;
|
||||
export var createClass: Function;
|
|
@ -1,25 +0,0 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<h2>Params</h2>
|
||||
<form>
|
||||
Depth:
|
||||
<input type="number" name="depth" placeholder="depth" value="9">
|
||||
<br>
|
||||
<button>Apply</button>
|
||||
</form>
|
||||
|
||||
<h2>AngularJS/Dart 1.x tree benchmark</h2>
|
||||
<p>
|
||||
<button id="destroyDom">destroyDom</button>
|
||||
<button id="createDom">createDom</button>
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<tree data="initData"></tree>
|
||||
</div>
|
||||
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
|
@ -1,107 +0,0 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
// tree benchmark in AngularJS 1.x
|
||||
import {getIntParameter, bindAction} from '@angular/testing/src/benchmark_util';
|
||||
declare var angular: any;
|
||||
|
||||
export function main() {
|
||||
angular.bootstrap(document.querySelector('tree'), ['app']);
|
||||
}
|
||||
|
||||
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) {
|
||||
const transcludeFn;
|
||||
return {
|
||||
compile: function(element, attrs) {
|
||||
const expr = $parse('!!' + attrs.treeIf);
|
||||
const template = '<tree data="' + attrs.treeIf + '"></tree>';
|
||||
let transclude;
|
||||
return function($scope, $element, $attrs) {
|
||||
if (!transclude) {
|
||||
transclude = $compile(template);
|
||||
}
|
||||
let childScope;
|
||||
let 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) {
|
||||
let count = 0;
|
||||
const maxDepth = getIntParameter('depth');
|
||||
|
||||
bindAction('#destroyDom', destroyDom);
|
||||
bindAction('#createDom', createDom);
|
||||
|
||||
function destroyDom() {
|
||||
$rootScope.$apply(function() { $rootScope.initData = new TreeNode('', null, null); });
|
||||
}
|
||||
|
||||
function createDom() {
|
||||
const 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