Skip to content

Commit a20bfa2

Browse files
committed
Conditionally enable native perf events
1 parent 2e717f2 commit a20bfa2

File tree

4 files changed

+39
-23
lines changed

4 files changed

+39
-23
lines changed

src/compiler/performance.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,19 @@ namespace ts.performance {
115115
}
116116

117117
/** Enables (and resets) performance measurements for the compiler. */
118-
export function enable() {
118+
export function enable(system: System = sys) {
119119
if (!enabled) {
120120
enabled = true;
121121
perfHooks ||= tryGetNativePerformanceHooks();
122122
if (perfHooks) {
123-
performanceImpl = perfHooks.performance;
124-
timeorigin = performanceImpl.timeOrigin;
123+
timeorigin = perfHooks.performance.timeOrigin;
124+
// NodeJS's Web Performance API is currently slower than expected, but we'd still like
125+
// to be able to leverage native trace events when node is run with either `--cpu-prof`
126+
// or `--prof`, if we're running with our own `--generateCpuProfile` flag, or when
127+
// running in debug mode (since its possible to generate a cpu profile while debugging).
128+
if (perfHooks.shouldWriteNativeEvents || system?.cpuProfilingEnabled?.() || system?.debugMode) {
129+
performanceImpl = perfHooks.performance;
130+
}
125131
}
126132
}
127133
return true;

src/compiler/performanceCore.ts

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ namespace ts {
44
// between browsers and NodeJS:
55

66
export interface PerformanceHooks {
7+
/** Indicates whether we should write native performance events */
8+
shouldWriteNativeEvents: boolean;
79
performance: Performance;
810
PerformanceObserver: PerformanceObserverConstructor;
911
}
@@ -37,6 +39,7 @@ namespace ts {
3739
export type PerformanceEntryList = PerformanceEntry[];
3840

3941
// Browser globals for the Web Performance User Timings API
42+
declare const process: any;
4043
declare const performance: Performance | undefined;
4144
declare const PerformanceObserver: PerformanceObserverConstructor | undefined;
4245

@@ -55,44 +58,49 @@ namespace ts {
5558
typeof PerformanceObserver === "function" &&
5659
hasRequiredAPI(performance, PerformanceObserver)) {
5760
return {
61+
// For now we always write native performance events when running in the browser. We may
62+
// make this conditional in the future if we find that native web performance hooks
63+
// in the browser also slow down compilation.
64+
shouldWriteNativeEvents: true,
5865
performance,
5966
PerformanceObserver
6067
};
6168
}
6269
}
6370

6471
function tryGetNodePerformanceHooks(): PerformanceHooks | undefined {
65-
if (typeof module === "object" && typeof require === "function") {
72+
if (typeof process !== "undefined" && process.nextTick && !process.browser && typeof module === "object" && typeof require === "function") {
6673
try {
67-
const { performance, PerformanceObserver } = require("perf_hooks") as typeof import("perf_hooks");
68-
if (hasRequiredAPI(performance, PerformanceObserver)) {
74+
let performance: Performance;
75+
const { performance: nodePerformance, PerformanceObserver } = require("perf_hooks") as typeof import("perf_hooks");
76+
if (hasRequiredAPI(nodePerformance, PerformanceObserver)) {
77+
performance = nodePerformance;
6978
// There is a bug in Node's performance.measure prior to 12.16.3/13.13.0 that does not
7079
// match the Web Performance API specification. Node's implementation did not allow
7180
// optional `start` and `end` arguments for `performance.measure`.
7281
// See https://github.com/nodejs/node/pull/32651 for more information.
7382
const version = new Version(process.versions.node);
7483
const range = new VersionRange("<12.16.3 || 13 <13.13");
7584
if (range.test(version)) {
76-
return {
77-
performance: {
78-
get timeOrigin() { return performance.timeOrigin; },
79-
now() { return performance.now(); },
80-
mark(name) { return performance.mark(name); },
81-
measure(name, start = "nodeStart", end?) {
82-
if (end === undefined) {
83-
end = "__performance.measure-fix__";
84-
performance.mark(end);
85-
}
86-
performance.measure(name, start, end);
87-
if (end === "__performance.measure-fix__") {
88-
performance.clearMarks("__performance.measure-fix__");
89-
}
85+
performance = {
86+
get timeOrigin() { return nodePerformance.timeOrigin; },
87+
now() { return nodePerformance.now(); },
88+
mark(name) { return nodePerformance.mark(name); },
89+
measure(name, start = "nodeStart", end?) {
90+
if (end === undefined) {
91+
end = "__performance.measure-fix__";
92+
nodePerformance.mark(end);
9093
}
91-
},
92-
PerformanceObserver
94+
nodePerformance.measure(name, start, end);
95+
if (end === "__performance.measure-fix__") {
96+
nodePerformance.clearMarks("__performance.measure-fix__");
97+
}
98+
}
9399
};
94100
}
95101
return {
102+
// By default, only write native events when generating a cpu profile or using the v8 profiler.
103+
shouldWriteNativeEvents: false,
96104
performance,
97105
PerformanceObserver
98106
};

src/compiler/sys.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,7 @@ namespace ts {
11161116
exit(exitCode?: number): void;
11171117
/*@internal*/ enableCPUProfiler?(path: string, continuation: () => void): boolean;
11181118
/*@internal*/ disableCPUProfiler?(continuation: () => void): boolean;
1119+
/*@internal*/ cpuProfilingEnabled?(): boolean;
11191120
realpath?(path: string): string;
11201121
/*@internal*/ getEnvironmentVariable(name: string): string;
11211122
/*@internal*/ tryEnableSourceMapsForHost?(): void;
@@ -1286,6 +1287,7 @@ namespace ts {
12861287
},
12871288
enableCPUProfiler,
12881289
disableCPUProfiler,
1290+
cpuProfilingEnabled: () => !!activeSession || contains(process.execArgv, "--cpu-prof") || contains(process.execArgv, "--prof"),
12891291
realpath,
12901292
debugMode: !!process.env.NODE_INSPECTOR_IPC || !!process.env.VSCODE_INSPECTOR_OPTIONS || some(<string[]>process.execArgv, arg => /^--(inspect|debug)(-brk)?(=\d+)?$/i.test(arg)),
12911293
tryEnableSourceMapsForHost() {

src/executeCommandLine/executeCommandLine.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ namespace ts {
662662

663663
function enableStatisticsAndTracing(system: System, compilerOptions: CompilerOptions, isBuildMode: boolean) {
664664
if (canReportDiagnostics(system, compilerOptions)) {
665-
performance.enable();
665+
performance.enable(system);
666666
}
667667

668668
if (canTrace(system, compilerOptions)) {

0 commit comments

Comments
 (0)