Skip to content

Commit fcbdf02

Browse files
committed
feat(perf): port table scrolling benchmark to Angular 2
1 parent 93c18f5 commit fcbdf02

File tree

21 files changed

+1119
-11
lines changed

21 files changed

+1119
-11
lines changed

modules/angular2/src/change_detection/proto_change_detector.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ function _operationToFunction(operation:string):Function {
360360
}
361361

362362
function s(v) {
363-
return isPresent(v) ? '' + v : '';
363+
return isPresent(v) ? `${v}` : '';
364364
}
365365

366366
function _interpolationFn(strings:List) {

modules/angular2/src/core/compiler/view.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,8 @@ export class ProtoView {
411411
// view might get dehydrated, in between the event queuing up and
412412
// firing.
413413
if (view.hydrated()) {
414-
MapWrapper.set(locals, '\$event', event);
414+
// HACK
415+
MapWrapper.set(locals, `$event`, event);
415416
var context = new ContextWithVariableBindings(view.context, locals);
416417
expr.eval(context);
417418
}

modules/angular2/src/facade/collection.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class StringMapWrapper {
7171
}
7272

7373
class ListWrapper {
74-
static List clone(List l) => new List.from(l);
74+
static List clone(Iterable l) => new List.from(l);
7575
static List create() => new List();
7676
static List createFixedSize(int size) => new List(size);
7777
static get(List m, int k) => m[k];
@@ -137,6 +137,9 @@ class ListWrapper {
137137
}
138138
return true;
139139
}
140+
static List slice(List l, int from, int to) {
141+
return l.sublist(from, to);
142+
}
140143
}
141144

142145
bool isListLikeIterable(obj) => obj is Iterable;

modules/angular2/src/facade/collection.es6

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ export class ListWrapper {
176176
}
177177
return true;
178178
}
179+
static slice(l:List, from:int, to:int):List {
180+
return l.slice(from, to);
181+
}
179182
}
180183

181184
export function isListLikeIterable(obj):boolean {

modules/angular2/src/facade/math.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,8 @@ class Math {
66
static num pow(num x, num exponent) {
77
return math.pow(x, exponent);
88
}
9+
10+
static num min(num a, num b) => math.min(a, b);
11+
12+
static num floor(num a) => a.floor();
913
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
var perfUtil = require('../../angular2/e2e_test/perf_util');
2+
3+
describe('ng2 naive infinite scroll benchmark', function () {
4+
5+
var URL = 'benchmarks/src/naive_infinite_scroll/index.html';
6+
7+
afterEach(perfUtil.verifyNoBrowserErrors);
8+
9+
[1, 2, 4].forEach(function(appSize) {
10+
it('should run scroll benchmark and collect stats for appSize = ' +
11+
appSize, function() {
12+
perfUtil.runBenchmark({
13+
url: URL,
14+
id: 'ng2.naive_infinite_scroll',
15+
work: function() {
16+
browser.executeScript(
17+
'document.querySelector("scroll-app /deep/ #reset-btn").click()');
18+
browser.executeScript(
19+
'document.querySelector("scroll-app /deep/ #run-btn").click()');
20+
browser.wait(() => {
21+
return $('#done').getText().then(
22+
function() { return true; },
23+
function() { return false; });
24+
}, 10000);
25+
},
26+
params: [{
27+
name: 'appSize', value: appSize
28+
}, {
29+
name: 'iterationCount', value: 20, scale: 'linear'
30+
}, {
31+
name: 'scrollIncrement', value: 40
32+
}]
33+
});
34+
});
35+
});
36+
37+
});
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
var testUtil = require('../../angular2/e2e_test/test_util');
2+
3+
describe('ng2 naive infinite scroll benchmark', function () {
4+
5+
var URL = 'benchmarks/src/naive_infinite_scroll/index.html';
6+
7+
afterEach(testUtil.verifyNoBrowserErrors);
8+
9+
it('should not throw errors', function() {
10+
browser.get(URL);
11+
browser.executeScript(
12+
'document.querySelector("scroll-app /deep/ #reset-btn").click()');
13+
browser.executeScript(
14+
'document.querySelector("scroll-app /deep/ #run-btn").click()');
15+
browser.wait(() => {
16+
return $('#done').getText().then(
17+
function() { return true; },
18+
function() { return false; });
19+
}, 10000);
20+
});
21+
22+
});

modules/benchmarks/src/index.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
<li>
2121
<a href="tree/tree_benchmark.html">Tree benchmark</a>
2222
</li>
23+
<li>
24+
<a href="naive_infinite_scroll/index.html">Naive infinite scroll benchmark</a>
25+
</li>
2326
</ul>
2427
</body>
2528
</html>
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import {int, isPresent} from 'angular2/src/facade/lang';
2+
import {reflector} from 'angular2/src/reflection/reflection';
3+
import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util';
4+
import {bootstrap, Component, Template, TemplateConfig, ViewPort, Compiler}
5+
from 'angular2/angular2';
6+
import {PromiseWrapper} from 'angular2/src/facade/async';
7+
import {ListWrapper} from 'angular2/src/facade/collection';
8+
import {ScrollAreaComponent} from './scroll_area';
9+
import {NgIf, NgRepeat} from 'angular2/directives';
10+
import {DOM, document, Element} from 'angular2/src/facade/dom';
11+
12+
export class App {
13+
scrollAreas:List<int>;
14+
iterationCount:int;
15+
scrollIncrement:int;
16+
17+
constructor() {
18+
var appSize = getIntParameter('appSize');
19+
this.iterationCount = getIntParameter('iterationCount');
20+
this.scrollIncrement = getIntParameter('scrollIncrement');
21+
appSize = appSize > 1 ? appSize - 1 : 0; // draw at least one table
22+
this.scrollAreas = [];
23+
for (var i = 0; i < appSize; i++) {
24+
ListWrapper.push(this.scrollAreas, i);
25+
}
26+
// TODO(tbosch): change to bindAction when it works in pub serve
27+
DOM.on(DOM.query('scroll-app /deep/ #run-btn'), 'click', (_) => {
28+
this.runBenchmark();
29+
});
30+
DOM.on(DOM.query('scroll-app /deep/ #reset-btn'), 'click', (_) => {
31+
this._getScrollDiv().scrollTop = 0;
32+
var existingMarker = this._locateFinishedMarker();
33+
if (isPresent(existingMarker)) {
34+
DOM.removeChild(document.body, existingMarker);
35+
}
36+
});
37+
}
38+
39+
runBenchmark() {
40+
var scrollDiv = this._getScrollDiv();
41+
var n:int = this.iterationCount;
42+
var scheduleScroll;
43+
scheduleScroll = () => {
44+
PromiseWrapper.setTimeout(() => {
45+
scrollDiv.scrollTop += this.scrollIncrement;
46+
n--;
47+
if (n > 0) {
48+
scheduleScroll();
49+
} else {
50+
this._scheduleFinishedMarker();
51+
}
52+
}, 0);
53+
}
54+
scheduleScroll();
55+
}
56+
57+
// Puts a marker indicating that the test is finished.
58+
_scheduleFinishedMarker() {
59+
var existingMarker = this._locateFinishedMarker();
60+
if (isPresent(existingMarker)) {
61+
// Nothing to do, the marker is already there
62+
return;
63+
}
64+
PromiseWrapper.setTimeout(() => {
65+
var finishedDiv = DOM.createElement('div');
66+
finishedDiv.id = 'done';
67+
DOM.setInnerHTML(finishedDiv, 'Finished');
68+
DOM.appendChild(document.body, finishedDiv);
69+
}, 0);
70+
}
71+
72+
_locateFinishedMarker():Element {
73+
return DOM.querySelector(document.body, '#done');
74+
}
75+
76+
_getScrollDiv() {
77+
return DOM.query('body /deep/ #testArea /deep/ #scrollDiv');
78+
}
79+
}
80+
81+
export function setupReflectorForApp() {
82+
reflector.registerType(App, {
83+
'factory': () => { return new App(); },
84+
'parameters': [],
85+
'annotations': [
86+
new Component({
87+
selector: 'scroll-app',
88+
template: new TemplateConfig({
89+
directives: [ScrollAreaComponent, NgIf, NgRepeat],
90+
inline: `
91+
<div>
92+
<div style="display: flex">
93+
<scroll-area id="testArea"></scroll-area>
94+
<div style="padding-left: 20px">
95+
<button id="run-btn">Run</button>
96+
<button id="reset-btn">Reset</button>
97+
</div>
98+
</div>
99+
<div template="ng-if scrollAreas.length > 0">
100+
<p>Following tables are only here to add weight to the UI:</p>
101+
<scroll-area template="ng-repeat #scrollArea in scrollAreas"></scroll-area>
102+
</div>
103+
</div>`
104+
})
105+
})
106+
]
107+
});
108+
}

0 commit comments

Comments
 (0)