Better performance metrics

Summary:
Current metrics are deltas from an initial set timestamp. This works but is limiting or affecting the overall accuracy of them.

The aim of this task is to replace the deltas with actual measurements for the operations.

This way we can add/remove operations in between which will not create any impact of them.

Reviewed By: LukeDefeo

Differential Revision: D44026823

fbshipit-source-id: fd7d62c4eab86bab8239b44beecd5c133f6d11c7
This commit is contained in:
Lorenzo Blasa
2023-03-16 07:35:44 -07:00
committed by Facebook GitHub Bot
parent 6cc4705ae4
commit 5d0e0137d5
3 changed files with 74 additions and 36 deletions

View File

@@ -7,31 +7,31 @@
* @format
*/
import {PerfStatsEvent} from '../types';
import {PerformanceStatsEvent} from '../types';
import React from 'react';
import {DataSource, DataTable, DataTableColumn} from 'flipper-plugin';
export function PerfStats(props: {events: DataSource<PerfStatsEvent, number>}) {
export function PerfStats(props: {
events: DataSource<PerformanceStatsEvent, number>;
}) {
return (
<DataTable<PerfStatsEvent> dataSource={props.events} columns={columns} />
<DataTable<PerformanceStatsEvent>
dataSource={props.events}
columns={columns}
/>
);
}
function formatDiff(start: number, end: number): string {
const ms = end - start;
function formatDiff(ms: number): string {
return `${ms.toFixed(0)}ms`;
}
const columns: DataTableColumn<PerfStatsEvent>[] = [
const columns: DataTableColumn<PerformanceStatsEvent>[] = [
{
key: 'txId',
title: 'TXID',
onRender: (row: PerfStatsEvent) => {
try {
return new Date(row.txId).toISOString();
} catch {
return row.txId;
}
onRender: (row: PerformanceStatsEvent) => {
return row.txId;
},
},
{
@@ -45,53 +45,50 @@ const columns: DataTableColumn<PerfStatsEvent>[] = [
{
key: 'start',
title: 'Start',
onRender: (row: PerfStatsEvent) => {
onRender: (row: PerformanceStatsEvent) => {
return new Date(row.start).toISOString();
},
},
{
key: 'traversalComplete',
key: 'traversalMS',
title: 'Traversal time (Main thread)',
onRender: (row: PerfStatsEvent) => {
return formatDiff(row.start, row.traversalComplete);
onRender: (row: PerformanceStatsEvent) => {
return formatDiff(row.traversalMS);
},
},
{
key: 'snapshotComplete',
key: 'snapshotMS',
title: 'Snapshot time (Main thread)',
onRender: (row: PerfStatsEvent) => {
return formatDiff(row.traversalComplete, row.snapshotComplete);
onRender: (row: PerformanceStatsEvent) => {
return formatDiff(row.snapshotMS);
},
},
{
key: 'queuingComplete',
key: 'queuingMS',
title: 'Queuing time',
onRender: (row: PerfStatsEvent) => {
return formatDiff(row.snapshotComplete, row.queuingComplete);
onRender: (row: PerformanceStatsEvent) => {
return formatDiff(row.queuingMS);
},
},
{
key: 'deferredComputationComplete',
key: 'deferredComputationMS',
title: 'Deferred processing time',
onRender: (row: PerfStatsEvent) => {
return formatDiff(row.queuingComplete, row.deferredComputationComplete);
onRender: (row: PerformanceStatsEvent) => {
return formatDiff(row.deferredComputationMS);
},
},
{
key: 'serializationComplete',
key: 'serializationMS',
title: 'Serialization time',
onRender: (row: PerfStatsEvent) => {
return formatDiff(
row.deferredComputationComplete,
row.serializationComplete,
);
onRender: (row: PerformanceStatsEvent) => {
return formatDiff(row.serializationMS);
},
},
{
key: 'socketComplete',
key: 'socketMS',
title: 'Socket send time',
onRender: (row: PerfStatsEvent) => {
return formatDiff(row.serializationComplete, row.socketComplete);
onRender: (row: PerformanceStatsEvent) => {
return formatDiff(row.socketMS);
},
},
];

View File

@@ -21,7 +21,7 @@ import {
FrameworkEventType,
Metadata,
MetadataId,
PerfStatsEvent,
PerformanceStatsEvent,
Snapshot,
UINode,
} from './types';
@@ -73,11 +73,34 @@ export function plugin(client: PluginClient<Events>) {
});
});
const perfEvents = createDataSource<PerfStatsEvent, 'txId'>([], {
const perfEvents = createDataSource<PerformanceStatsEvent, 'txId'>([], {
key: 'txId',
limit: 10 * 1024,
});
/**
* The message handling below is a temporary measure for a couple of weeks until
* clients migrate to the newer message/format.
*/
client.onMessage('perfStats', (event) => {
const stat = {
txId: event.txId,
observerType: event.observerType,
nodesCount: event.nodesCount,
start: event.start,
traversalMS: event.traversalComplete - event.start,
snapshotMS: event.snapshotComplete - event.traversalComplete,
queuingMS: event.queuingComplete - event.snapshotComplete,
deferredComputationMS:
event.deferredComputationComplete - event.queuingComplete,
serializationMS:
event.serializationComplete - event.deferredComputationComplete,
socketMS: event.socketComplete - event.serializationComplete,
};
client.logger.track('performance', 'subtreeUpdate', stat, 'ui-debugger');
perfEvents.append(stat);
});
client.onMessage('performanceStats', (event) => {
client.logger.track('performance', 'subtreeUpdate', event, 'ui-debugger');
perfEvents.append(event);
});

View File

@@ -12,6 +12,7 @@ export type Events = {
subtreeUpdate: SubtreeUpdateEvent;
coordinateUpdate: CoordinateUpdateEvent;
perfStats: PerfStatsEvent;
performanceStats: PerformanceStatsEvent;
metadataUpdate: UpdateMetadataEvent;
};
@@ -47,6 +48,10 @@ export type InitEvent = {
frameworkEventMetadata?: FrameworkEventMetadata[];
};
/**
* @deprecated This performance event should not be used and soon will
* be removed. PerformanceStatsEvent should be used instead.
*/
export type PerfStatsEvent = {
txId: number;
observerType: string;
@@ -60,6 +65,19 @@ export type PerfStatsEvent = {
nodesCount: number;
};
export type PerformanceStatsEvent = {
txId: number;
observerType: string;
nodesCount: number;
start: number;
traversalMS: number;
snapshotMS: number;
queuingMS: number;
deferredComputationMS: number;
serializationMS: number;
socketMS: number;
};
export type UpdateMetadataEvent = {
attributeMetadata: Record<MetadataId, Metadata>;
};