improve logger

This commit is contained in:
dwelle 2022-08-20 18:01:26 +02:00
parent d731a6463c
commit 1d65536360
3 changed files with 88 additions and 25 deletions

View File

@ -264,51 +264,99 @@ import {
} from "../element/Hyperlink"; } from "../element/Hyperlink";
import { shouldShowBoundingBox } from "../element/transformHandles"; import { shouldShowBoundingBox } from "../element/transformHandles";
const TIMES_AGGR: Record<string, { t: number; times: number[] }> = {}; let TIMES_AGGR: Record<string, { t: number; times: number[] }> = {};
const TIMES_AVG: Record<string, { times: number[] }> = {}; let TIMES_AVG: Record<
string,
{ t: number; times: number[]; avg: number | null }
> = {};
window.DEBUG_LOG_TIMES = true; window.DEBUG_LOG_TIMES = true;
setInterval(() => { let lastDebugLogCall = 0;
let DEBUG_LOG_INTERVAL_ID: null | number = null;
const setupInterval = () => {
if (DEBUG_LOG_INTERVAL_ID === null) {
console.info("%c(starting perf recording)", "color: lime");
DEBUG_LOG_INTERVAL_ID = window.setInterval(debugLogger, 1000);
}
lastDebugLogCall = Date.now();
};
const lessPrecise = (num: number, precision = 5) =>
parseFloat(num.toPrecision(precision));
const getAvgFrameTime = (times: number[]) =>
lessPrecise(times.reduce((a, b) => a + b) / times.length);
const getFps = (frametime: number) => lessPrecise(1000 / frametime);
const debugLogger = () => {
if (Date.now() - lastDebugLogCall > 600 && DEBUG_LOG_INTERVAL_ID !== null) {
window.clearInterval(DEBUG_LOG_INTERVAL_ID);
DEBUG_LOG_INTERVAL_ID = null;
for (const [name, { avg }] of Object.entries(TIMES_AVG)) {
if (avg != null) {
console.info(
`%c${name} run avg: ${avg}ms (${getFps(avg)} fps)`,
"color: blue",
);
}
}
console.info("%c(stopping perf recording)", "color: red");
TIMES_AGGR = {};
TIMES_AVG = {};
return;
}
if (window.DEBUG_LOG_TIMES) { if (window.DEBUG_LOG_TIMES) {
for (const [name, { t, times }] of Object.entries(TIMES_AGGR)) { for (const [name, { t, times }] of Object.entries(TIMES_AGGR)) {
if (times.length) { if (times.length) {
console.info( console.info(
name, name,
times.reduce((a, b) => a + b), lessPrecise(times.reduce((a, b) => a + b) / times.length),
times.sort((a, b) => a - b), times.sort((a, b) => a - b).map((x) => lessPrecise(x)),
); );
TIMES_AGGR[name] = { t, times: [] }; TIMES_AGGR[name] = { t, times: [] };
} }
} }
for (const [name, { times }] of Object.entries(TIMES_AVG)) { for (const [name, { t, times, avg }] of Object.entries(TIMES_AVG)) {
if (times.length) { if (times.length) {
console.info( const avgFrameTime = getAvgFrameTime(times);
name, console.info(name, `${avgFrameTime}ms (${getFps(avgFrameTime)} fps)`);
parseFloat( TIMES_AVG[name] = {
(times.reduce((a, b) => a + b) / times.length).toPrecision(5), t,
), times: [],
times.sort((a, b) => a - b), avg:
); avg != null ? getAvgFrameTime([avg, avgFrameTime]) : avgFrameTime,
TIMES_AVG[name] = { times: [] }; };
} }
} }
} }
}, 1000); };
window.logTime = (name: string, time?: number) => { window.logTime = (name: string, time?: number) => {
setupInterval();
const now = performance.now();
const { t, times } = (TIMES_AGGR[name] = TIMES_AGGR[name] || { const { t, times } = (TIMES_AGGR[name] = TIMES_AGGR[name] || {
t: 0, t: 0,
times: [], times: [],
}); });
if (t) { if (t) {
times.push(time != null ? time : Date.now() - t); times.push(time != null ? time : now - t);
} }
TIMES_AGGR[name].t = Date.now(); TIMES_AGGR[name].t = now;
}; };
window.logTimeAverage = (name: string, time: number) => { window.logTimeAverage = (name: string, time?: number) => {
const { times } = (TIMES_AVG[name] = TIMES_AVG[name] || { times: [] }); setupInterval();
times.push(time); const now = performance.now();
const { t, times } = (TIMES_AVG[name] = TIMES_AVG[name] || {
t: 0,
times: [],
});
if (t) {
times.push(time != null ? time : now - t);
}
TIMES_AVG[name].t = now;
}; };
const deviceContextInitialValue = { const deviceContextInitialValue = {
@ -525,6 +573,24 @@ class App extends React.Component<AppProps, AppState> {
private __renderUI = true; private __renderUI = true;
private perfTest = (runs = 180, initial = true) => {
if (initial) {
console.time("perfTest");
} else if (!runs) {
console.timeEnd("perfTest");
}
if (runs) {
requestAnimationFrame((id) => {
for (const element of this.scene.getNonDeletedElements()) {
mutateElement(element, {
x: element.x + 1,
});
}
this.perfTest(runs - 1, false);
});
}
};
public render() { public render() {
const selectedElement = getSelectedElements( const selectedElement = getSelectedElements(
this.scene.getNonDeletedElements(), this.scene.getNonDeletedElements(),

2
src/global.d.ts vendored
View File

@ -17,7 +17,7 @@ interface Window {
EXCALIDRAW_THROTTLE_RENDER: boolean | undefined; EXCALIDRAW_THROTTLE_RENDER: boolean | undefined;
gtag: Function; gtag: Function;
logTime: (name: string, time?: number) => void; logTime: (name: string, time?: number) => void;
logTimeAverage: (name: string, time: number) => void; logTimeAverage: (name: string, time?: number) => void;
DEBUG_LOG_TIMES: boolean; DEBUG_LOG_TIMES: boolean;
} }

View File

@ -310,8 +310,6 @@ const renderLinearElementPointHighlight = (
context.restore(); context.restore();
}; };
let t = performance.now();
export const _renderScene = ({ export const _renderScene = ({
elements, elements,
appState, appState,
@ -332,8 +330,7 @@ export const _renderScene = ({
if (canvas === null) { if (canvas === null) {
return { atLeastOneVisibleElement: false }; return { atLeastOneVisibleElement: false };
} }
window.logTimeAverage("renderScene", performance.now() - t); window.logTimeAverage("renderScene");
t = performance.now();
const { const {
renderScrollbars = true, renderScrollbars = true,
renderSelection = true, renderSelection = true,