perf(ivy): introduce a node-based micro-benchmarks harness (#32510)
PR Close #32510
This commit is contained in:
parent
66df745721
commit
2895edc9c6
@ -9,6 +9,7 @@ ts_library(
|
|||||||
),
|
),
|
||||||
deps = [
|
deps = [
|
||||||
"//packages/core",
|
"//packages/core",
|
||||||
|
"@npm//@types/node",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ yarn bazel build //packages/core/test/render3/perf:{name}.min_debug.es2015.js --
|
|||||||
|
|
||||||
### Run
|
### Run
|
||||||
|
|
||||||
time node dist/bin/packages/core/test/render3/perf/{name}.min_debug.es2015.js
|
node dist/bin/packages/core/test/render3/perf/{name}.min_debug.es2015.js
|
||||||
|
|
||||||
### Profile
|
### Profile
|
||||||
|
|
||||||
@ -19,4 +19,4 @@ The actual benchmark code has calls that will start (`console.profile`) and stop
|
|||||||
In all the above commands {name} should be replaced with the actual benchmark (folder) name, ex.:
|
In all the above commands {name} should be replaced with the actual benchmark (folder) name, ex.:
|
||||||
- build: `yarn bazel build //packages/core/test/render3/perf:noop_change_detection.min_debug.es2015.js --define=compile=aot`
|
- build: `yarn bazel build //packages/core/test/render3/perf:noop_change_detection.min_debug.es2015.js --define=compile=aot`
|
||||||
- run: `time node dist/bin/packages/core/test/render3/perf/noop_change_detection.min_debug.es2015.js`
|
- run: `time node dist/bin/packages/core/test/render3/perf/noop_change_detection.min_debug.es2015.js`
|
||||||
- profile: `node --no-turbo-inlining --inspect-brk dist/bin/packages/core/test/render3/perf/noop_change_detection.min_debug.es2015.js`
|
- profile: `node --no-turbo-inlining --inspect-brk dist/bin/packages/core/test/render3/perf/noop_change_detection.min_debug.es2015.js profile`
|
||||||
|
@ -11,6 +11,7 @@ import {ɵɵtext} from '../../../../src/render3/instructions/text';
|
|||||||
import {RenderFlags} from '../../../../src/render3/interfaces/definition';
|
import {RenderFlags} from '../../../../src/render3/interfaces/definition';
|
||||||
import {TNodeType, TViewNode} from '../../../../src/render3/interfaces/node';
|
import {TNodeType, TViewNode} from '../../../../src/render3/interfaces/node';
|
||||||
import {resetComponentState} from '../../../../src/render3/state';
|
import {resetComponentState} from '../../../../src/render3/state';
|
||||||
|
import {createBenchmark} from '../micro_bench';
|
||||||
import {createAndRenderLView} from '../setup';
|
import {createAndRenderLView} from '../setup';
|
||||||
|
|
||||||
`<div>
|
`<div>
|
||||||
@ -72,9 +73,17 @@ resetComponentState();
|
|||||||
// create view once so we don't profile first template pass
|
// create view once so we don't profile first template pass
|
||||||
createAndRenderLView(null, embeddedTView, viewTNode);
|
createAndRenderLView(null, embeddedTView, viewTNode);
|
||||||
|
|
||||||
// profile create views (run templates in creation mode)
|
// scenario to benchmark
|
||||||
console.profile('create');
|
const elementTextCreate = createBenchmark('element and text create', 500000, 20);
|
||||||
for (let i = 0; i < 500000; i++) {
|
const createTime = elementTextCreate('create');
|
||||||
|
|
||||||
|
console.profile('element_text_create');
|
||||||
|
while (createTime.run()) {
|
||||||
|
while (createTime()) {
|
||||||
createAndRenderLView(null, embeddedTView, viewTNode);
|
createAndRenderLView(null, embeddedTView, viewTNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
console.profileEnd();
|
console.profileEnd();
|
||||||
|
|
||||||
|
// report results
|
||||||
|
elementTextCreate.report();
|
71
packages/core/test/render3/perf/micro_bench.ts
Normal file
71
packages/core/test/render3/perf/micro_bench.ts
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/**
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
const performance = require('perf_hooks').performance;
|
||||||
|
|
||||||
|
interface Benchmark {
|
||||||
|
(versionName: string): Profile;
|
||||||
|
report(fn?: (report: string) => void): void;
|
||||||
|
}
|
||||||
|
interface Profile {
|
||||||
|
(): boolean;
|
||||||
|
profileName: string;
|
||||||
|
run(): boolean;
|
||||||
|
bestTime: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createBenchmark(
|
||||||
|
benchmarkName: string, iterationCount: number, runs: number = 50): Benchmark {
|
||||||
|
const profiles: Profile[] = [];
|
||||||
|
|
||||||
|
const benchmark = function Benchmark(profileName: string): Profile {
|
||||||
|
let iterationCounter: number = iterationCount;
|
||||||
|
const profile: Profile = function Profile() {
|
||||||
|
if (iterationCounter === 0) {
|
||||||
|
iterationCounter = iterationCount;
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
iterationCounter--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} as Profile;
|
||||||
|
let lastTimestamp = 0;
|
||||||
|
let runCount = runs;
|
||||||
|
profile.run = function() {
|
||||||
|
const now = performance.now();
|
||||||
|
if (lastTimestamp !== 0) {
|
||||||
|
const time = now - lastTimestamp;
|
||||||
|
profile.bestTime = Math.min(profile.bestTime, time);
|
||||||
|
}
|
||||||
|
lastTimestamp = now;
|
||||||
|
if (runCount === 0) {
|
||||||
|
runCount = runs;
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
runCount--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
profile.profileName = profileName;
|
||||||
|
profile.bestTime = Number.MAX_SAFE_INTEGER;
|
||||||
|
profiles.push(profile);
|
||||||
|
return profile;
|
||||||
|
} as Benchmark;
|
||||||
|
|
||||||
|
benchmark.report = function(fn?: (report: string) => void) {
|
||||||
|
setTimeout(() => {
|
||||||
|
const fastest = profiles.reduce((previous: Profile, current: Profile) => {
|
||||||
|
return (previous.bestTime < current.bestTime) ? previous : current;
|
||||||
|
});
|
||||||
|
(fn || console.log)(`Benchmark: ${benchmarkName}\n${profiles.map((profile: Profile) => {
|
||||||
|
const percent = (100 - profile.bestTime / fastest.bestTime * 100).toFixed(0);
|
||||||
|
return profile.profileName + ': ' + profile.bestTime.toFixed(0) + ` us(${percent} %) `;
|
||||||
|
}).join('\n')}`);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return benchmark;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user