Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/performance/browser/inputLatencyContrib.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { inputLatency } from '../../../../base/browser/performance.js';
7
import { RunOnceScheduler } from '../../../../base/common/async.js';
8
import { Event } from '../../../../base/common/event.js';
9
import { Disposable, MutableDisposable } from '../../../../base/common/lifecycle.js';
10
import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js';
11
import { IWorkbenchContribution } from '../../../common/contributions.js';
12
import { IEditorService } from '../../../services/editor/common/editorService.js';
13
14
export class InputLatencyContrib extends Disposable implements IWorkbenchContribution {
15
private readonly _listener = this._register(new MutableDisposable());
16
private readonly _scheduler: RunOnceScheduler;
17
18
constructor(
19
@IEditorService private readonly _editorService: IEditorService,
20
@ITelemetryService private readonly _telemetryService: ITelemetryService
21
) {
22
super();
23
24
// The current sampling strategy is when the active editor changes, start sampling and
25
// report the results after 60 seconds. It's done this way as we don't want to sample
26
// everything, just somewhat randomly, and using an interval would utilize CPU when the
27
// application is inactive.
28
this._scheduler = this._register(new RunOnceScheduler(() => {
29
this._logSamples();
30
this._setupListener();
31
}, 60000));
32
33
34
// Only log 1% of users selected randomly to reduce the volume of data
35
if (Math.random() <= 0.01) {
36
this._setupListener();
37
}
38
39
}
40
41
private _setupListener(): void {
42
this._listener.value = Event.once(this._editorService.onDidActiveEditorChange)(() => this._scheduler.schedule());
43
}
44
45
private _logSamples(): void {
46
const measurements = inputLatency.getAndClearMeasurements();
47
if (!measurements) {
48
return;
49
}
50
51
type InputLatencyStatisticFragment = {
52
owner: 'tyriar';
53
comment: 'Represents a set of statistics collected about input latencies';
54
average: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The average time it took to execute.' };
55
max: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The maximum time it took to execute.' };
56
min: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The minimum time it took to execute.' };
57
};
58
59
type PerformanceInputLatencyClassification = {
60
owner: 'tyriar';
61
comment: 'This is a set of samples of the time (in milliseconds) that various events took when typing in the editor';
62
keydown: InputLatencyStatisticFragment;
63
input: InputLatencyStatisticFragment;
64
render: InputLatencyStatisticFragment;
65
total: InputLatencyStatisticFragment;
66
sampleCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The number of samples measured.' };
67
};
68
69
type PerformanceInputLatencyEvent = inputLatency.IInputLatencyMeasurements;
70
71
this._telemetryService.publicLog2<PerformanceInputLatencyEvent, PerformanceInputLatencyClassification>('performance.inputLatency', {
72
keydown: measurements.keydown,
73
input: measurements.input,
74
render: measurements.render,
75
total: measurements.total,
76
sampleCount: measurements.sampleCount
77
});
78
}
79
}
80
81