Skip to content

Commit b289f0c

Browse files
committed
rename startupTimer to performance, support mark and measure, drop promise support, add more marks to slowly phase out old timers
1 parent 10fe0ac commit b289f0c

12 files changed

Lines changed: 157 additions & 190 deletions

File tree

build/gulpfile.vscode.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ const vscodeResources = [
6868
'out-build/bootstrap-amd.js',
6969
'out-build/paths.js',
7070
'out-build/vs/**/*.{svg,png,cur,html}',
71-
'out-build/vs/base/node/startupTimers.js',
71+
'out-build/vs/base/common/performance.js',
7272
'out-build/vs/base/node/{stdForkStart.js,terminateProcess.sh}',
7373
'out-build/vs/base/browser/ui/octiconLabel/octicons/**',
7474
'out-build/vs/workbench/browser/media/*-theme.css',

src/main.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ if (process.argv.indexOf('--prof-startup') >= 0) {
1212
profiler.startProfiling('main', true);
1313
}
1414

15+
var perf = require('./vs/base/common/performance');
16+
perf.mark('main:started');
17+
1518
// Perf measurements
1619
global.perfStartTime = Date.now();
1720

@@ -218,6 +221,7 @@ var nodeCachedDataDir = getNodeCachedDataDir().then(function (value) {
218221

219222
// Load our code once ready
220223
app.once('ready', function () {
224+
perf.mark('main:appReady');
221225
global.perfAppReady = Date.now();
222226
var nlsConfig = getNLSConfiguration();
223227
process.env['VSCODE_NLS_CONFIG'] = JSON.stringify(nlsConfig);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
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+
export interface PerformanceEntry {
7+
readonly type: 'mark' | 'measure';
8+
readonly name: string;
9+
readonly startTime: number;
10+
readonly duration: number;
11+
}
12+
13+
export function mark(name: string): void;
14+
export function measure(name: string, from?: string, to?: string): void;
15+
export function time(name: string): { stop(): void };
16+
export function getEntries(type?: 'mark' | 'measure'): PerformanceEntry[];
17+
export function importEntries(entries: PerformanceEntry[]): void;

src/vs/base/common/performance.js

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
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+
'use strict';
7+
8+
/*global define*/
9+
10+
// This module can be loaded in an amd and commonjs-context.
11+
// Because we want both instances to use the same perf-data
12+
// we store them globally
13+
global._performanceEntries = global._performanceEntries || [];
14+
15+
if (typeof define !== "function" && typeof module === "object" && typeof module.exports === "object") {
16+
// this is commonjs, fake amd
17+
global.define = function (dep, callback) {
18+
module.exports = callback();
19+
global.define = undefined;
20+
};
21+
}
22+
23+
define([], function () {
24+
25+
// const _now = global.performance && performance.now ? performance.now : Date.now
26+
const _now = Date.now;
27+
28+
class PerformanceEntry {
29+
constructor(type, name, startTime, duration) {
30+
this.type = type;
31+
this.name = name;
32+
this.startTime = startTime;
33+
this.duration = duration;
34+
}
35+
}
36+
37+
function _getEntry(type, name) {
38+
for (let i = global._performanceEntries.length - 1; i >= 0; i--) {
39+
if (
40+
(type === undefined || global._performanceEntries[i].type === type) &&
41+
(name === undefined || global._performanceEntries[i].name === name)
42+
) {
43+
return global._performanceEntries[i];
44+
}
45+
}
46+
}
47+
48+
function importEntries(entries) {
49+
global._performanceEntries.splice(0, 0, ...entries);
50+
}
51+
52+
function getEntries(type, name) {
53+
return global._performanceEntries.filter(entry => {
54+
return (type === undefined || entry.type === type) &&
55+
(name === undefined || entry.name === name);
56+
}).sort((a, b) => {
57+
return a.startTime - b.startTime;
58+
});
59+
}
60+
61+
function mark(name) {
62+
const entry = new PerformanceEntry('mark', name, _now(), 0);
63+
global._performanceEntries.push(entry);
64+
if (typeof console.timeStamp === 'function') {
65+
console.timeStamp(name);
66+
}
67+
}
68+
69+
function time(name) {
70+
let from = `${name}/start`;
71+
mark(from);
72+
return { stop() { measure(name, from); } };
73+
}
74+
75+
function measure(name, from, to) {
76+
77+
let startTime;
78+
let duration;
79+
let now = _now();
80+
81+
if (!from) {
82+
startTime = now;
83+
} else {
84+
startTime = _getEntry(undefined, from).startTime;
85+
}
86+
87+
if (!to) {
88+
duration = now - startTime;
89+
} else {
90+
duration = _getEntry(undefined, to).startTime - startTime;
91+
}
92+
93+
const entry = new PerformanceEntry('measure', name, startTime, duration);
94+
global._performanceEntries.push(entry);
95+
}
96+
97+
var exports = {
98+
mark: mark,
99+
measure: measure,
100+
time: time,
101+
getEntries: getEntries,
102+
importEntries: importEntries
103+
};
104+
105+
return exports;
106+
});

src/vs/base/node/startupTimers.d.ts

Lines changed: 0 additions & 39 deletions
This file was deleted.

src/vs/base/node/startupTimers.js

Lines changed: 0 additions & 128 deletions
This file was deleted.

src/vs/code/electron-main/window.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import { ICodeWindow } from 'vs/platform/windows/electron-main/windows';
2626
import { IWorkspaceIdentifier, IWorkspacesMainService } from 'vs/platform/workspaces/common/workspaces';
2727
import { IBackupMainService } from 'vs/platform/backup/common/backup';
2828
import { ICommandAction } from 'vs/platform/actions/common/actions';
29+
import { mark, getEntries } from 'vs/base/common/performance';
2930

3031
export interface IWindowState {
3132
width?: number;
@@ -507,6 +508,7 @@ export class CodeWindow implements ICodeWindow {
507508
}
508509

509510
// Load URL
511+
mark('main:loadWindow');
510512
this._win.loadURL(this.getUrl(config));
511513

512514
// Make window visible if it did not open in N seconds because this indicates an error
@@ -578,6 +580,7 @@ export class CodeWindow implements ICodeWindow {
578580
windowConfiguration.backgroundColor = this.getBackgroundColor();
579581

580582
// Perf Counters
583+
windowConfiguration.perfEntries = getEntries();
581584
windowConfiguration.perfStartTime = global.perfStartTime;
582585
windowConfiguration.perfAppReady = global.perfAppReady;
583586
windowConfiguration.perfWindowLoadTime = Date.now();
@@ -971,4 +974,4 @@ export class CodeWindow implements ICodeWindow {
971974

972975
this._win = null; // Important to dereference the window object to allow for GC
973976
}
974-
}
977+
}

src/vs/platform/windows/common/windows.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { ParsedArgs } from 'vs/platform/environment/common/environment';
1414
import { IWorkspaceIdentifier, IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces';
1515
import { IRecentlyOpened } from 'vs/platform/history/common/history';
1616
import { ICommandAction } from 'vs/platform/actions/common/actions';
17+
import { PerformanceEntry } from 'vs/base/common/performance';
1718

1819
export const IWindowsService = createDecorator<IWindowsService>('windowsService');
1920

@@ -255,6 +256,7 @@ export interface IWindowConfiguration extends ParsedArgs, IOpenFileRequest {
255256
backgroundColor?: string;
256257
accessibilitySupport?: boolean;
257258

259+
perfEntries: PerformanceEntry[];
258260
perfStartTime?: number;
259261
perfAppReady?: number;
260262
perfWindowLoadTime?: number;
@@ -263,4 +265,4 @@ export interface IWindowConfiguration extends ParsedArgs, IOpenFileRequest {
263265
export interface IRunActionInWindowRequest {
264266
id: string;
265267
from: 'menu' | 'touchbar' | 'mouse';
266-
}
268+
}

src/vs/workbench/electron-browser/actions.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifi
4545
import { FileKind } from 'vs/platform/files/common/files';
4646
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
4747
import { IExtensionService } from 'vs/platform/extensions/common/extensions';
48-
import { ticks } from 'vs/base/node/startupTimers';
48+
import { getEntries } from 'vs/base/common/performance';
4949

5050
// --- actions
5151

@@ -367,9 +367,10 @@ export class ShowStartupPerformance extends Action {
367367

368368
(<any>console).group('Raw Startup Timers (CSV)');
369369
let value = `Name\tStart\tDuration\n`;
370-
let offset = ticks()[0].started;
371-
for (const tick of ticks()) {
372-
value += `${tick.name}\t${tick.started - offset}\t${tick.duration}\n`;
370+
const entries = getEntries('measure');
371+
let offset = entries[0].startTime;
372+
for (const entry of entries) {
373+
value += `${entry.name}\t${entry.startTime - offset}\t${entry.duration}\n`;
373374
}
374375
console.log(value);
375376
(<any>console).groupEnd();

0 commit comments

Comments
 (0)