Skip to content

Commit 68da001

Browse files
committed
perf(Change Detection): remove the usage of getters/setters
- Firefox is 2.4x faster (90 vs 221ms) - Chrome is 24% slower (15.5 vs 12.5ms) Chrome is still 5.8x faster than Firefox
1 parent 2c4a2f5 commit 68da001

File tree

3 files changed

+35
-35
lines changed

3 files changed

+35
-35
lines changed

modules/change_detection/src/record.js

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,11 @@ export class Record {
130130
this._mode = protoRecord._mode;
131131

132132
// Return early for collections, further init delayed until updateContext()
133-
if (this.isCollection) return;
133+
if (this.isCollection()) return;
134134

135135
this.currentValue = _fresh;
136136

137-
var type = this.type;
137+
var type = this.getType();
138138

139139
if (type === RECORD_TYPE_CONST) {
140140
this.funcOrValue = protoRecord.funcOrValue;
@@ -159,22 +159,22 @@ export class Record {
159159
}
160160
}
161161

162-
// todo(vicb): getter / setters are much slower than regular methods
163-
// todo(vicb): update the whole code base
164-
get type():int {
162+
// getters & setters perform much worse on some browsers
163+
// see http://jsperf.com/vicb-getter-vs-function
164+
getType():int {
165165
return this._mode & RECORD_TYPE_MASK;
166166
}
167167

168-
set type(value:int) {
168+
setType(value:int) {
169169
this._mode = (this._mode & ~RECORD_TYPE_MASK) | value;
170170
}
171171

172-
get disabled():boolean {
172+
isDisabled():boolean {
173173
return (this._mode & RECORD_FLAG_DISABLED) === RECORD_FLAG_DISABLED;
174174
}
175175

176176
isEnabled():boolean {
177-
return ! this.disabled;
177+
return !this.isDisabled();
178178
}
179179

180180
_setDisabled(value:boolean) {
@@ -210,11 +210,11 @@ export class Record {
210210
this._setDisabled(true);
211211
}
212212

213-
get isImplicitReceiver():boolean {
213+
isImplicitReceiver():boolean {
214214
return (this._mode & RECORD_FLAG_IMPLICIT_RECEIVER) === RECORD_FLAG_IMPLICIT_RECEIVER;
215215
}
216216

217-
get isCollection():boolean {
217+
isCollection():boolean {
218218
return (this._mode & RECORD_FLAG_COLLECTION) === RECORD_FLAG_COLLECTION;
219219
}
220220

@@ -223,7 +223,7 @@ export class Record {
223223
}
224224

225225
check():boolean {
226-
if (this.isCollection) {
226+
if (this.isCollection()) {
227227
return this._checkCollection();
228228
} else {
229229
return this._checkSingleRecord();
@@ -250,7 +250,7 @@ export class Record {
250250

251251
// return whether the content has changed
252252
_checkCollection():boolean {
253-
switch(this.type) {
253+
switch(this.getType()) {
254254
case RECORD_TYPE_KEY_VALUE:
255255
var kvChangeDetector:KeyValueChanges = this.currentValue;
256256
return kvChangeDetector.check(this.context);
@@ -266,12 +266,12 @@ export class Record {
266266
return true;
267267

268268
default:
269-
throw new BaseException(`Unsupported record type (${this.type})`);
269+
throw new BaseException(`Unsupported record type (${this.getType()})`);
270270
}
271271
}
272272

273273
_calculateNewValue() {
274-
switch (this.type) {
274+
switch (this.getType()) {
275275
case RECORD_TYPE_PROPERTY:
276276
return this.funcOrValue(this.context);
277277

@@ -291,7 +291,7 @@ export class Record {
291291
return this.funcOrValue;
292292

293293
default:
294-
throw new BaseException(`Unsupported record type (${this.type})`);
294+
throw new BaseException(`Unsupported record type (${this.getType()})`);
295295
}
296296
}
297297

@@ -304,25 +304,25 @@ export class Record {
304304
this.context = value;
305305
this.enable();
306306

307-
if (this.isCollection) {
307+
if (this.isCollection()) {
308308
if (ArrayChanges.supports(value)) {
309-
if (this.type != RECORD_TYPE_ARRAY) {
310-
this.type = RECORD_TYPE_ARRAY;
309+
if (this.getType() != RECORD_TYPE_ARRAY) {
310+
this.setType(RECORD_TYPE_ARRAY);
311311
this.currentValue = new ArrayChanges();
312312
}
313313
return;
314314
}
315315

316316
if (KeyValueChanges.supports(value)) {
317-
if (this.type != RECORD_TYPE_KEY_VALUE) {
318-
this.type = RECORD_TYPE_KEY_VALUE;
317+
if (this.getType() != RECORD_TYPE_KEY_VALUE) {
318+
this.setType(RECORD_TYPE_KEY_VALUE);
319319
this.currentValue = new KeyValueChanges();
320320
}
321321
return;
322322
}
323323

324324
if (isBlank(value)) {
325-
this.type = RECORD_TYPE_NULL;
325+
this.setType(RECORD_TYPE_NULL);
326326
} else {
327327
throw new BaseException("Collection records must be array like, map like or null");
328328
}
@@ -333,8 +333,8 @@ export class Record {
333333
return !(this.dest instanceof Record);
334334
}
335335

336-
get isMarkerRecord() {
337-
return this.type == RECORD_TYPE_MARKER;
336+
isMarkerRecord():boolean {
337+
return this.getType() == RECORD_TYPE_MARKER;
338338
}
339339

340340
expressionMemento() {
@@ -357,8 +357,8 @@ export class Record {
357357
if (this.isEnabled()) return this.nextEnabled;
358358

359359
var record = this.next;
360-
while (isPresent(record) && record.disabled) {
361-
if (record.isMarkerRecord && record.recordRange.disabled) {
360+
while (isPresent(record) && record.isDisabled()) {
361+
if (record.isMarkerRecord() && record.recordRange.disabled) {
362362
record = record.recordRange.tailRecord.next;
363363
} else {
364364
record = record.next;
@@ -378,8 +378,8 @@ export class Record {
378378
if (this.isEnabled()) return this.prevEnabled;
379379

380380
var record = this.prev;
381-
while (isPresent(record) && record.disabled) {
382-
if (record.isMarkerRecord && record.recordRange.disabled) {
381+
while (isPresent(record) && record.isDisabled()) {
382+
if (record.isMarkerRecord() && record.recordRange.disabled) {
383383
record = record.recordRange.headRecord.prev;
384384
} else {
385385
record = record.prev;

modules/change_detection/src/record_range.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ export class RecordRange {
122122
var lastRecord = this.tailRecord.prev;
123123

124124
_link(lastRecord, record);
125-
if (!lastRecord.disabled) {
125+
if (!lastRecord.isDisabled()) {
126126
_linkEnabled(lastRecord, record);
127127
}
128128
_link(record, this.tailRecord);
@@ -210,8 +210,8 @@ export class RecordRange {
210210
*/
211211
findFirstEnabledRecord() {
212212
var record = this.headRecord.next;
213-
while (record !== this.tailRecord && record.disabled) {
214-
if (record.isMarkerRecord && record.recordRange.disabled) {
213+
while (record !== this.tailRecord && record.isDisabled()) {
214+
if (record.isMarkerRecord() && record.recordRange.disabled) {
215215
record = record.recordRange.tailRecord.next;
216216
} else {
217217
record = record.next;
@@ -234,8 +234,8 @@ export class RecordRange {
234234
*/
235235
findLastEnabledRecord() {
236236
var record = this.tailRecord.prev;
237-
while (record !== this.headRecord && record.disabled) {
238-
if (record.isMarkerRecord && record.recordRange.disabled) {
237+
while (record !== this.headRecord && record.isDisabled()) {
238+
if (record.isMarkerRecord() && record.recordRange.disabled) {
239239
record = record.recordRange.headRecord.prev;
240240
} else {
241241
record = record.prev;
@@ -256,7 +256,7 @@ export class RecordRange {
256256
record != null;
257257
record = record.next) {
258258

259-
if (record.isImplicitReceiver) {
259+
if (record.isImplicitReceiver()) {
260260
this._setContextForRecord(context, record);
261261
}
262262
}

modules/change_detection/test/record_range_spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,8 @@ export function main() {
212212
record2.disable();
213213
record3.disable();
214214

215-
expect(record2.disabled).toBeTruthy();
216-
expect(record3.disabled).toBeTruthy();
215+
expect(record2.isDisabled()).toBeTruthy();
216+
expect(record3.isDisabled()).toBeTruthy();
217217

218218
expect(enabledRecords(rr, recordNames)).toEqual(['record1', 'record4']);
219219
});

0 commit comments

Comments
 (0)