Skip to content

Commit 405d8e9

Browse files
committed
Report aggregate statistics for solution as well as some solution perf numbers
1 parent 7593eee commit 405d8e9

File tree

4 files changed

+377
-202
lines changed

4 files changed

+377
-202
lines changed

src/compiler/performance.ts

+131-115
Original file line numberDiff line numberDiff line change
@@ -1,146 +1,162 @@
11
/*@internal*/
22
/** Performance measurements for the compiler. */
3-
namespace ts.performance {
4-
let perfHooks: PerformanceHooks | undefined;
5-
// when set, indicates the implementation of `Performance` to use for user timing.
6-
// when unset, indicates user timing is unavailable or disabled.
7-
let performanceImpl: Performance | undefined;
8-
9-
export interface Timer {
3+
namespace ts {
4+
interface Timer {
105
enter(): void;
116
exit(): void;
127
}
138

14-
export function createTimerIf(condition: boolean, measureName: string, startMarkName: string, endMarkName: string) {
15-
return condition ? createTimer(measureName, startMarkName, endMarkName) : nullTimer;
16-
}
9+
const nullTimer: Timer = { enter: noop, exit: noop };
10+
export const performance = createPerformanceTracker();
11+
export const solutionPerformance = createPerformanceTracker();
12+
13+
function createPerformanceTracker() {
14+
let perfHooks: PerformanceHooks | undefined;
15+
// when set, indicates the implementation of `Performance` to use for user timing.
16+
// when unset, indicates user timing is unavailable or disabled.
17+
let performanceImpl: Performance | undefined;
18+
let enabled = false;
19+
let timeorigin = timestamp();
20+
const marks = new Map<string, number>();
21+
const counts = new Map<string, number>();
22+
const durations = new Map<string, number>();
1723

18-
export function createTimer(measureName: string, startMarkName: string, endMarkName: string): Timer {
19-
let enterCount = 0;
2024
return {
21-
enter,
22-
exit
25+
createTimerIf,
26+
createTimer,
27+
mark,
28+
measure,
29+
getCount,
30+
getDuration,
31+
forEachMeasure,
32+
isEnabled,
33+
enable,
34+
disable,
2335
};
2436

25-
function enter() {
26-
if (++enterCount === 1) {
27-
mark(startMarkName);
28-
}
37+
function createTimerIf(condition: boolean, measureName: string, startMarkName: string, endMarkName: string) {
38+
return condition ? createTimer(measureName, startMarkName, endMarkName) : nullTimer;
2939
}
3040

31-
function exit() {
32-
if (--enterCount === 0) {
33-
mark(endMarkName);
34-
measure(measureName, startMarkName, endMarkName);
41+
function createTimer(measureName: string, startMarkName: string, endMarkName: string): Timer {
42+
let enterCount = 0;
43+
return {
44+
enter,
45+
exit
46+
};
47+
48+
function enter() {
49+
if (++enterCount === 1) {
50+
mark(startMarkName);
51+
}
3552
}
36-
else if (enterCount < 0) {
37-
Debug.fail("enter/exit count does not match.");
53+
54+
function exit() {
55+
if (--enterCount === 0) {
56+
mark(endMarkName);
57+
measure(measureName, startMarkName, endMarkName);
58+
}
59+
else if (enterCount < 0) {
60+
Debug.fail("enter/exit count does not match.");
61+
}
3862
}
3963
}
40-
}
4164

42-
export const nullTimer: Timer = { enter: noop, exit: noop };
43-
44-
let enabled = false;
45-
let timeorigin = timestamp();
46-
const marks = new Map<string, number>();
47-
const counts = new Map<string, number>();
48-
const durations = new Map<string, number>();
49-
50-
/**
51-
* Marks a performance event.
52-
*
53-
* @param markName The name of the mark.
54-
*/
55-
export function mark(markName: string) {
56-
if (enabled) {
57-
const count = counts.get(markName) ?? 0;
58-
counts.set(markName, count + 1);
59-
marks.set(markName, timestamp());
60-
performanceImpl?.mark(markName);
65+
/**
66+
* Marks a performance event.
67+
*
68+
* @param markName The name of the mark.
69+
*/
70+
function mark(markName: string) {
71+
if (enabled) {
72+
const count = counts.get(markName) ?? 0;
73+
counts.set(markName, count + 1);
74+
marks.set(markName, timestamp());
75+
performanceImpl?.mark(markName);
76+
}
6177
}
62-
}
6378

64-
/**
65-
* Adds a performance measurement with the specified name.
66-
*
67-
* @param measureName The name of the performance measurement.
68-
* @param startMarkName The name of the starting mark. If not supplied, the point at which the
69-
* profiler was enabled is used.
70-
* @param endMarkName The name of the ending mark. If not supplied, the current timestamp is
71-
* used.
72-
*/
73-
export function measure(measureName: string, startMarkName?: string, endMarkName?: string) {
74-
if (enabled) {
75-
const end = (endMarkName !== undefined ? marks.get(endMarkName) : undefined) ?? timestamp();
76-
const start = (startMarkName !== undefined ? marks.get(startMarkName) : undefined) ?? timeorigin;
77-
const previousDuration = durations.get(measureName) || 0;
78-
durations.set(measureName, previousDuration + (end - start));
79-
performanceImpl?.measure(measureName, startMarkName, endMarkName);
79+
/**
80+
* Adds a performance measurement with the specified name.
81+
*
82+
* @param measureName The name of the performance measurement.
83+
* @param startMarkName The name of the starting mark. If not supplied, the point at which the
84+
* profiler was enabled is used.
85+
* @param endMarkName The name of the ending mark. If not supplied, the current timestamp is
86+
* used.
87+
*/
88+
function measure(measureName: string, startMarkName: string, endMarkName: string) {
89+
if (enabled) {
90+
const end = marks.get(endMarkName) ?? timestamp();
91+
const start = marks.get(startMarkName) ?? timeorigin;
92+
const previousDuration = durations.get(measureName) || 0;
93+
durations.set(measureName, previousDuration + (end - start));
94+
performanceImpl?.measure(measureName, startMarkName, endMarkName);
95+
}
8096
}
81-
}
8297

83-
/**
84-
* Gets the number of times a marker was encountered.
85-
*
86-
* @param markName The name of the mark.
87-
*/
88-
export function getCount(markName: string) {
89-
return counts.get(markName) || 0;
90-
}
98+
/**
99+
* Gets the number of times a marker was encountered.
100+
*
101+
* @param markName The name of the mark.
102+
*/
103+
function getCount(markName: string) {
104+
return counts.get(markName) || 0;
105+
}
91106

92-
/**
93-
* Gets the total duration of all measurements with the supplied name.
94-
*
95-
* @param measureName The name of the measure whose durations should be accumulated.
96-
*/
97-
export function getDuration(measureName: string) {
98-
return durations.get(measureName) || 0;
99-
}
107+
/**
108+
* Gets the total duration of all measurements with the supplied name.
109+
*
110+
* @param measureName The name of the measure whose durations should be accumulated.
111+
*/
112+
function getDuration(measureName: string) {
113+
return durations.get(measureName) || 0;
114+
}
100115

101-
/**
102-
* Iterate over each measure, performing some action
103-
*
104-
* @param cb The action to perform for each measure
105-
*/
106-
export function forEachMeasure(cb: (measureName: string, duration: number) => void) {
107-
durations.forEach((duration, measureName) => cb(measureName, duration));
108-
}
116+
/**
117+
* Iterate over each measure, performing some action
118+
*
119+
* @param cb The action to perform for each measure
120+
*/
121+
function forEachMeasure(cb: (measureName: string, duration: number) => void) {
122+
durations.forEach((duration, measureName) => cb(measureName, duration));
123+
}
109124

110-
/**
111-
* Indicates whether the performance API is enabled.
112-
*/
113-
export function isEnabled() {
114-
return enabled;
115-
}
125+
/**
126+
* Indicates whether the performance API is enabled.
127+
*/
128+
function isEnabled() {
129+
return enabled;
130+
}
116131

117-
/** Enables (and resets) performance measurements for the compiler. */
118-
export function enable(system: System = sys) {
119-
if (!enabled) {
120-
enabled = true;
121-
perfHooks ||= tryGetNativePerformanceHooks();
122-
if (perfHooks) {
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;
132+
/** Enables (and resets) performance measurements for the compiler. */
133+
function enable(system: System = sys) {
134+
if (!enabled) {
135+
enabled = true;
136+
perfHooks ||= tryGetNativePerformanceHooks();
137+
if (perfHooks) {
138+
timeorigin = perfHooks.performance.timeOrigin;
139+
// NodeJS's Web Performance API is currently slower than expected, but we'd still like
140+
// to be able to leverage native trace events when node is run with either `--cpu-prof`
141+
// or `--prof`, if we're running with our own `--generateCpuProfile` flag, or when
142+
// running in debug mode (since its possible to generate a cpu profile while debugging).
143+
if (perfHooks.shouldWriteNativeEvents || system?.cpuProfilingEnabled?.() || system?.debugMode) {
144+
performanceImpl = perfHooks.performance;
145+
}
130146
}
131147
}
148+
return true;
132149
}
133-
return true;
134-
}
135150

136-
/** Disables performance measurements for the compiler. */
137-
export function disable() {
138-
if (enabled) {
139-
marks.clear();
140-
counts.clear();
141-
durations.clear();
142-
performanceImpl = undefined;
143-
enabled = false;
151+
/** Disables performance measurements for the compiler. */
152+
function disable() {
153+
if (enabled) {
154+
marks.clear();
155+
counts.clear();
156+
durations.clear();
157+
performanceImpl = undefined;
158+
enabled = false;
159+
}
144160
}
145161
}
146162
}

src/compiler/sourcemap.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ namespace ts {
55
}
66

77
export function createSourceMapGenerator(host: EmitHost, file: string, sourceRoot: string, sourcesDirectoryPath: string, generatorOptions: SourceMapGeneratorOptions): SourceMapGenerator {
8-
const { enter, exit } = generatorOptions.extendedDiagnostics
9-
? performance.createTimer("Source Map", "beforeSourcemap", "afterSourcemap")
10-
: performance.nullTimer;
8+
const { enter, exit } = performance.createTimerIf(!!generatorOptions.extendedDiagnostics, "Source Map", "beforeSourcemap", "afterSourcemap");
119

1210
// Current source map file and its index in the sources list
1311
const rawSources: string[] = [];

0 commit comments

Comments
 (0)