test(ivy): clean up class_binding perf tests for readability (#33413)
PR Close #33413
This commit is contained in:
parent
26f44c0d6b
commit
7a280b1a21
|
@ -7,159 +7,221 @@
|
||||||
*/
|
*/
|
||||||
import {ɵɵproperty} from '@angular/core/src/core';
|
import {ɵɵproperty} from '@angular/core/src/core';
|
||||||
import {AttributeMarker, TAttributes} from '@angular/core/src/render3/interfaces/node';
|
import {AttributeMarker, TAttributes} from '@angular/core/src/render3/interfaces/node';
|
||||||
|
|
||||||
import {ɵɵelement} from '../../../../src/render3/instructions/element';
|
import {ɵɵelement} from '../../../../src/render3/instructions/element';
|
||||||
import {ɵɵclassMap, ɵɵclassProp} from '../../../../src/render3/instructions/styling';
|
import {ɵɵclassMap, ɵɵclassProp} from '../../../../src/render3/instructions/styling';
|
||||||
import {ComponentTemplate, RenderFlags} from '../../../../src/render3/interfaces/definition';
|
import {ComponentTemplate, RenderFlags} from '../../../../src/render3/interfaces/definition';
|
||||||
import {createBenchmark} from '../micro_bench';
|
import {Benchmark, createBenchmark} from '../micro_bench';
|
||||||
import {setupTestHarness} from '../setup';
|
import {setupTestHarness} from '../setup';
|
||||||
|
|
||||||
|
const PROFILE_CREATE = true;
|
||||||
|
const PROFILE_UPDATE = true;
|
||||||
|
const PROFILE_NOOP = true;
|
||||||
|
|
||||||
const CLASSES_1_A = 'one';
|
|
||||||
const CLASSES_1_B = CLASSES_1_A.toUpperCase();
|
function benchmark(
|
||||||
const CLASSES_2_A = 'one two';
|
name: string, template: ComponentTemplate<any>, baselineTemplate: ComponentTemplate<any>) {
|
||||||
const CLASSES_2_B = CLASSES_2_A.toUpperCase();
|
const ivyHarness = setupTestHarness(template, 1, 1, 1000, context, consts);
|
||||||
const CLASSES_10_A = 'one two three four five six seven eight nine ten';
|
const baseHarness = setupTestHarness(baselineTemplate, 1, 1, 1000, context, consts);
|
||||||
const CLASSES_10_B = CLASSES_10_A.toUpperCase();
|
|
||||||
let toggleClasses = true;
|
if (PROFILE_CREATE) {
|
||||||
|
const benchmark = createBenchmark('class binding[create]: ' + name);
|
||||||
|
benchmarks.push(benchmark);
|
||||||
|
const ivyProfile = benchmark('styling');
|
||||||
|
console.profile(benchmark.name + ':' + ivyProfile.name);
|
||||||
|
while (ivyProfile()) {
|
||||||
|
ivyHarness.createEmbeddedLView();
|
||||||
|
}
|
||||||
|
console.profileEnd();
|
||||||
|
|
||||||
|
const baseProfile = benchmark('base');
|
||||||
|
console.profile(benchmark.name + ':' + baseProfile.name);
|
||||||
|
while (baseProfile()) {
|
||||||
|
baseHarness.createEmbeddedLView();
|
||||||
|
}
|
||||||
|
console.profileEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PROFILE_UPDATE) {
|
||||||
|
const benchmark = createBenchmark('class binding[update]: ' + name);
|
||||||
|
benchmarks.push(benchmark);
|
||||||
|
const ivyProfile = benchmark('styling');
|
||||||
|
console.profile(benchmark.name + ':' + ivyProfile.name);
|
||||||
|
while (ivyProfile()) {
|
||||||
|
toggle = !toggle;
|
||||||
|
ivyHarness.detectChanges();
|
||||||
|
}
|
||||||
|
console.profileEnd();
|
||||||
|
|
||||||
|
const baseProfile = benchmark('base');
|
||||||
|
console.profile(benchmark.name + ':' + baseProfile.name);
|
||||||
|
while (baseProfile()) {
|
||||||
|
toggle = !toggle;
|
||||||
|
baseHarness.detectChanges();
|
||||||
|
}
|
||||||
|
console.profileEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (PROFILE_NOOP) {
|
||||||
|
const benchmark = createBenchmark('class binding[noop]: ' + name);
|
||||||
|
benchmarks.push(benchmark);
|
||||||
|
const ivyProfile = benchmark('styling');
|
||||||
|
console.profile(benchmark.name + ':' + ivyProfile.name);
|
||||||
|
while (ivyProfile()) {
|
||||||
|
ivyHarness.detectChanges();
|
||||||
|
}
|
||||||
|
console.profileEnd();
|
||||||
|
|
||||||
|
const baseProfile = benchmark('base');
|
||||||
|
console.profile(benchmark.name + ':' + baseProfile.name);
|
||||||
|
while (baseProfile()) {
|
||||||
|
baseHarness.detectChanges();
|
||||||
|
}
|
||||||
|
console.profileEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const A_1 = 'one';
|
||||||
|
const B_1 = A_1.toUpperCase();
|
||||||
|
const A_10 = 'one two three four five six seven eight nine ten';
|
||||||
|
const B_10 = A_10.toUpperCase();
|
||||||
|
let toggle = true;
|
||||||
|
|
||||||
const consts: TAttributes[] = [
|
const consts: TAttributes[] = [
|
||||||
[AttributeMarker.Classes, 'A', 'B'] // 0
|
[AttributeMarker.Classes, 'A', 'B'] // 0
|
||||||
];
|
];
|
||||||
const context: any = {};
|
const context: any = {};
|
||||||
const createClassBindingBenchmark = createBenchmark('class binding: create:');
|
const benchmarks: Benchmark[] = [];
|
||||||
const updateClassBindingBenchmark = createBenchmark('class binding: update:');
|
|
||||||
const noopClassBindingBenchmark = createBenchmark('class binding: noop:');
|
|
||||||
function benchmark(name: string, template: ComponentTemplate<any>) {
|
|
||||||
const harness = setupTestHarness(template, 1, 1, 1000, context, consts);
|
|
||||||
|
|
||||||
const createProfile = createClassBindingBenchmark(name);
|
|
||||||
console.profile('create: ' + name);
|
|
||||||
while (createProfile()) {
|
|
||||||
harness.createEmbeddedLView();
|
|
||||||
}
|
|
||||||
console.profileEnd();
|
|
||||||
|
|
||||||
|
|
||||||
const updateProfile = updateClassBindingBenchmark(name);
|
|
||||||
console.profile('update: ' + name);
|
|
||||||
while (updateProfile()) {
|
|
||||||
toggleClasses = !toggleClasses;
|
|
||||||
harness.detectChanges();
|
|
||||||
}
|
|
||||||
console.profileEnd();
|
|
||||||
|
|
||||||
const noopProfile = noopClassBindingBenchmark(name);
|
|
||||||
console.profile('nop: ' + name);
|
|
||||||
while (noopProfile()) {
|
|
||||||
harness.detectChanges();
|
|
||||||
}
|
|
||||||
console.profileEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
`<div [class]="toggleClasses ? CLASSES_1_A : CLASSES_1_B">`;
|
|
||||||
benchmark(`[class]="CLASSES_1"`, function(rf: RenderFlags, ctx: any) {
|
|
||||||
if (rf & 1) {
|
|
||||||
ɵɵelement(0, 'div');
|
|
||||||
}
|
|
||||||
if (rf & 2) {
|
|
||||||
ɵɵclassMap(toggleClasses ? CLASSES_1_A : CLASSES_1_B);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
`<div [class]="toggleClasses ? CLASSES_2_A : CLASSES_2_B">`;
|
|
||||||
benchmark(`[class]="CLASSES_2"`, function(rf: RenderFlags, ctx: any) {
|
|
||||||
if (rf & 1) {
|
|
||||||
ɵɵelement(0, 'div');
|
|
||||||
}
|
|
||||||
if (rf & 2) {
|
|
||||||
ɵɵclassMap(toggleClasses ? CLASSES_2_A : CLASSES_2_B);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
`<div [class]="toggleClasses ? CLASSES_10_A : CLASSES_10_B">`;
|
|
||||||
benchmark(`[class]="CLASSES_10"`, function(rf: RenderFlags, ctx: any) {
|
|
||||||
if (rf & 1) {
|
|
||||||
ɵɵelement(0, 'div');
|
|
||||||
}
|
|
||||||
if (rf & 2) {
|
|
||||||
ɵɵclassMap(toggleClasses ? CLASSES_10_A : CLASSES_10_B);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
`<div class="A B">`;
|
|
||||||
benchmark(`class="A B"`, function(rf: RenderFlags, ctx: any) {
|
|
||||||
if (rf & 1) {
|
|
||||||
ɵɵelement(0, 'div', 0);
|
|
||||||
}
|
|
||||||
if (rf & 2) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
`<div class="A B"
|
|
||||||
[class]="toggleClasses ? CLASSES_1_A : CLASSES_1_B">`;
|
|
||||||
benchmark(`class="A B" [class]="CLASSES_1"`, function(rf: RenderFlags, ctx: any) {
|
|
||||||
if (rf & 1) {
|
|
||||||
ɵɵelement(0, 'div', 0);
|
|
||||||
}
|
|
||||||
if (rf & 2) {
|
|
||||||
ɵɵclassMap(toggleClasses ? CLASSES_1_A : CLASSES_1_B);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
`<div class="A B"
|
|
||||||
[class]="toggleClasses ? CLASSES_10_A : CLASSES_10_B">`;
|
|
||||||
benchmark(`class="A B" [class]="CLASSES_10"`, function(rf: RenderFlags, ctx: any) {
|
|
||||||
if (rf & 1) {
|
|
||||||
ɵɵelement(0, 'div', 0);
|
|
||||||
}
|
|
||||||
if (rf & 2) {
|
|
||||||
ɵɵclassMap(toggleClasses ? CLASSES_10_A : CLASSES_10_B);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
`<div class="A B"
|
|
||||||
[class]="toggleClasses ? CLASSES_1_A : CLASSES_1_B"
|
|
||||||
[class.foo]="toggleClasses">`;
|
|
||||||
benchmark(`class="A B" [class]="CLASSES_1" [class.foo]="exp"`, function(rf: RenderFlags, ctx: any) {
|
|
||||||
if (rf & 1) {
|
|
||||||
ɵɵelement(0, 'div', 0);
|
|
||||||
}
|
|
||||||
if (rf & 2) {
|
|
||||||
ɵɵclassMap(toggleClasses ? CLASSES_1_A : CLASSES_1_B);
|
|
||||||
ɵɵclassProp('foo', toggleClasses);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
`<div class="A B"
|
|
||||||
[class]="toggleClasses ? CLASSES_10_A : CLASSES_10_B"
|
|
||||||
[class.foo]="toggleClasses">`;
|
|
||||||
benchmark(
|
benchmark(
|
||||||
`class="A B" [class]="CLASSES_10" [class.foo]="exp"`, function(rf: RenderFlags, ctx: any) {
|
`<div class="A B">`,
|
||||||
|
function(rf: RenderFlags, ctx: any) {
|
||||||
if (rf & 1) {
|
if (rf & 1) {
|
||||||
ɵɵelement(0, 'div', 0);
|
ɵɵelement(0, 'div', 0);
|
||||||
}
|
}
|
||||||
if (rf & 2) {
|
},
|
||||||
ɵɵclassMap(toggleClasses ? CLASSES_10_A : CLASSES_10_B);
|
function(rf: RenderFlags, ctx: any) {
|
||||||
ɵɵclassProp('foo', toggleClasses);
|
if (rf & 1) {
|
||||||
|
ɵɵelement(0, 'div', 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
`<div [className]="toggleClasses ? CLASSES_10_A : CLASSES_10_B">`;
|
benchmark(
|
||||||
benchmark(`[className]="CLASSES_10"`, function(rf: RenderFlags, ctx: any) {
|
`<div [class]="toggle ? A_1 : B_1">`,
|
||||||
if (rf & 1) {
|
function(rf: RenderFlags, ctx: any) {
|
||||||
ɵɵelement(0, 'div');
|
if (rf & 1) {
|
||||||
}
|
ɵɵelement(0, 'div');
|
||||||
if (rf & 2) {
|
}
|
||||||
ɵɵproperty('className', toggleClasses ? CLASSES_10_A : CLASSES_10_B);
|
if (rf & 2) {
|
||||||
}
|
ɵɵclassMap(toggle ? A_1 : B_1);
|
||||||
});
|
}
|
||||||
|
},
|
||||||
|
function(rf: RenderFlags, ctx: any) {
|
||||||
|
if (rf & 1) {
|
||||||
|
ɵɵelement(0, 'div');
|
||||||
|
}
|
||||||
|
if (rf & 2) {
|
||||||
|
ɵɵproperty('className', toggle ? A_1 : B_1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
createClassBindingBenchmark.report();
|
benchmark(
|
||||||
updateClassBindingBenchmark.report();
|
`<div [class]="toggle ? A_10 : B_10">`,
|
||||||
noopClassBindingBenchmark.report();
|
function(rf: RenderFlags, ctx: any) {
|
||||||
|
if (rf & 1) {
|
||||||
|
ɵɵelement(0, 'div');
|
||||||
|
}
|
||||||
|
if (rf & 2) {
|
||||||
|
ɵɵclassMap(toggle ? A_10 : B_10);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function(rf: RenderFlags, ctx: any) {
|
||||||
|
if (rf & 1) {
|
||||||
|
ɵɵelement(0, 'div');
|
||||||
|
}
|
||||||
|
if (rf & 2) {
|
||||||
|
ɵɵproperty('className', toggle ? A_10 : B_10);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
benchmark(
|
||||||
|
`<div [class]="toggle ? A_1 : B_1">`,
|
||||||
|
function(rf: RenderFlags, ctx: any) {
|
||||||
|
if (rf & 1) {
|
||||||
|
ɵɵelement(0, 'div');
|
||||||
|
}
|
||||||
|
if (rf & 2) {
|
||||||
|
ɵɵclassMap(toggle ? A_1 : B_1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function(rf: RenderFlags, ctx: any) {
|
||||||
|
if (rf & 1) {
|
||||||
|
ɵɵelement(0, 'div');
|
||||||
|
}
|
||||||
|
if (rf & 2) {
|
||||||
|
ɵɵproperty('className', toggle ? A_1 : B_1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
benchmark(
|
||||||
|
`<div class="A B" [class]="toggle ? A_1 : B_1">`,
|
||||||
|
function(rf: RenderFlags, ctx: any) {
|
||||||
|
if (rf & 1) {
|
||||||
|
ɵɵelement(0, 'div', 0);
|
||||||
|
}
|
||||||
|
if (rf & 2) {
|
||||||
|
ɵɵclassMap(toggle ? A_1 : B_1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function(rf: RenderFlags, ctx: any) {
|
||||||
|
if (rf & 1) {
|
||||||
|
ɵɵelement(0, 'div', 1);
|
||||||
|
}
|
||||||
|
if (rf & 2) {
|
||||||
|
ɵɵproperty('className', toggle ? A_1 : B_1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
benchmark(
|
||||||
|
`<div class="A B" [class]="toggle ? A_10 : B_10">`,
|
||||||
|
function(rf: RenderFlags, ctx: any) {
|
||||||
|
if (rf & 1) {
|
||||||
|
ɵɵelement(0, 'div', 0);
|
||||||
|
}
|
||||||
|
if (rf & 2) {
|
||||||
|
ɵɵclassMap(toggle ? A_10 : B_10);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function(rf: RenderFlags, ctx: any) {
|
||||||
|
if (rf & 1) {
|
||||||
|
ɵɵelement(0, 'div', 1);
|
||||||
|
}
|
||||||
|
if (rf & 2) {
|
||||||
|
ɵɵproperty('className', toggle ? A_10 : B_10);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
benchmark(
|
||||||
|
`<div class="A B" [class]="toggle ? A_1 : B_1" [class.foo]="toggle">`,
|
||||||
|
function(rf: RenderFlags, ctx: any) {
|
||||||
|
if (rf & 1) {
|
||||||
|
ɵɵelement(0, 'div', 0);
|
||||||
|
}
|
||||||
|
if (rf & 2) {
|
||||||
|
ɵɵclassMap(toggle ? A_1 : B_1);
|
||||||
|
ɵɵclassProp('foo', toggle);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function(rf: RenderFlags, ctx: any) {
|
||||||
|
if (rf & 1) {
|
||||||
|
ɵɵelement(0, 'div', 1);
|
||||||
|
}
|
||||||
|
if (rf & 2) {
|
||||||
|
ɵɵproperty('className', toggle ? A_1 + 'foo' : B_1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
benchmarks.forEach(b => b.report());
|
||||||
|
|
|
@ -43,7 +43,7 @@ export function createBenchmark(benchmarkName: string): Benchmark {
|
||||||
iterationCounter = profile.iterationCount;
|
iterationCounter = profile.iterationCount;
|
||||||
runAgain = true;
|
runAgain = true;
|
||||||
// tslint:disable-next-line:no-console
|
// tslint:disable-next-line:no-console
|
||||||
console.log(profileName, '...');
|
console.log(benchmarkName, profileName, '...');
|
||||||
} else {
|
} else {
|
||||||
profile.sampleCount++;
|
profile.sampleCount++;
|
||||||
// we came to an end of a sample, compute the time.
|
// we came to an end of a sample, compute the time.
|
||||||
|
|
Loading…
Reference in New Issue