Skip to content

Commit 96ba0f2

Browse files
committed
Added metrics for printing
1 parent b5dec0b commit 96ba0f2

7 files changed

Lines changed: 141 additions & 110 deletions

File tree

src/compiler/binder.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,7 @@ namespace ts {
9696
export function bindSourceFile(file: SourceFile, options: CompilerOptions) {
9797
performance.mark("bindStart");
9898
binder(file, options);
99-
performance.mark("bindEnd");
100-
performance.measure("bindTime", "bindStart", "bindEnd");
99+
performance.measure("bindTime", "bindStart");
101100
}
102101

103102
function createBinder(): (file: SourceFile, options: CompilerOptions) => void {

src/compiler/checker.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16068,8 +16068,7 @@ namespace ts {
1606816068

1606916069
checkSourceFileWorker(node);
1607016070

16071-
performance.mark("checkEnd");
16072-
performance.measure("checkTime", "checkStart", "checkEnd");
16071+
performance.measure("checkTime", "checkStart");
1607316072
}
1607416073

1607516074
// Fully type check a source file and collect the relevant diagnostics.

src/compiler/comments.ts

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ namespace ts {
77
setSourceFile(sourceFile: SourceFile): void;
88
getLeadingComments(range: TextRange): CommentRange[];
99
getLeadingComments(range: TextRange, contextNode: Node, ignoreNodeCallback: (contextNode: Node) => boolean, getTextRangeCallback: (contextNode: Node) => TextRange): CommentRange[];
10-
getLeadingCommentsOfPosition(pos: number): CommentRange[];
1110
getTrailingComments(range: TextRange): CommentRange[];
1211
getTrailingComments(range: TextRange, contextNode: Node, ignoreNodeCallback: (contextNode: Node) => boolean, getTextRangeCallback: (contextNode: Node) => TextRange): CommentRange[];
1312
getTrailingCommentsOfPosition(pos: number): CommentRange[];
@@ -32,9 +31,9 @@ namespace ts {
3231

3332
// This maps start->end for a comment range. See `hasConsumedCommentRange` and
3433
// `consumeCommentRange` for usage.
35-
let consumedCommentRanges: number[];
36-
let leadingCommentRangePositions: boolean[];
37-
let trailingCommentRangePositions: boolean[];
34+
let consumedCommentRanges: Map<number>;
35+
let leadingCommentRangePositions: Map<boolean>;
36+
let trailingCommentRangePositions: Map<boolean>;
3837

3938
return compilerOptions.removeComments
4039
? createCommentRemovingWriter()
@@ -45,7 +44,6 @@ namespace ts {
4544
reset,
4645
setSourceFile,
4746
getLeadingComments(range: TextRange, contextNode?: Node, ignoreNodeCallback?: (contextNode: Node) => boolean, getTextRangeCallback?: (contextNode: Node) => TextRange): CommentRange[] { return undefined; },
48-
getLeadingCommentsOfPosition(pos: number): CommentRange[] { return undefined; },
4947
getTrailingComments(range: TextRange, contextNode?: Node, ignoreNodeCallback?: (contextNode: Node) => boolean, getTextRangeCallback?: (contextNode: Node) => TextRange): CommentRange[] { return undefined; },
5048
getTrailingCommentsOfPosition(pos: number): CommentRange[] { return undefined; },
5149
emitLeadingComments(range: TextRange, comments: CommentRange[], contextNode?: Node, getTextRangeCallback?: (contextNode: Node) => TextRange): void { },
@@ -69,7 +67,6 @@ namespace ts {
6967
reset,
7068
setSourceFile,
7169
getLeadingComments,
72-
getLeadingCommentsOfPosition,
7370
getTrailingComments,
7471
getTrailingCommentsOfPosition,
7572
emitLeadingComments,
@@ -81,9 +78,14 @@ namespace ts {
8178
function getLeadingComments(range: TextRange): CommentRange[];
8279
function getLeadingComments(range: TextRange, contextNode: Node, ignoreNodeCallback: (contextNode: Node) => boolean, getTextRangeCallback: (contextNode: Node) => TextRange): CommentRange[];
8380
function getLeadingComments(range: TextRange, contextNode?: Node, ignoreNodeCallback?: (contextNode: Node) => boolean, getTextRangeCallback?: (contextNode: Node) => TextRange) {
81+
performance.mark("commentStart");
82+
83+
let comments: CommentRange[] = [];
84+
let ignored = false;
8485
if (contextNode) {
8586
range = getTextRangeCallback(contextNode) || range;
8687
if (ignoreNodeCallback(contextNode)) {
88+
ignored = true;
8789
// If the node will not be emitted in JS, remove all the comments (normal,
8890
// pinned and `///`) associated with the node, unless it is a triple slash
8991
// comment at the top of the file.
@@ -97,15 +99,17 @@ namespace ts {
9799
// The first `///` will NOT be removed while the second one will be removed
98100
// even though both nodes will not be emitted.
99101
if (range.pos === 0) {
100-
return filter(getLeadingCommentsOfPosition(0), isTripleSlashComment);
102+
comments = filter(getLeadingCommentsOfPosition(0), isTripleSlashComment);
101103
}
102-
103-
return undefined;
104104
}
105105
}
106106

107+
if (!ignored) {
108+
comments = getLeadingCommentsOfPosition(range.pos);
109+
}
107110

108-
return getLeadingCommentsOfPosition(range.pos);
111+
performance.measure("commentTime", "commentStart");
112+
return comments;
109113
}
110114

111115
/**
@@ -127,15 +131,25 @@ namespace ts {
127131
function getTrailingComments(range: TextRange): CommentRange[];
128132
function getTrailingComments(range: TextRange, contextNode: Node, ignoreNodeCallback: (contextNode: Node) => boolean, getTextRangeCallback: (contextNode: Node) => TextRange): CommentRange[];
129133
function getTrailingComments(range: TextRange, contextNode?: Node, ignoreNodeCallback?: (contextNode: Node) => boolean, getTextRangeCallback?: (contextNode: Node) => TextRange) {
134+
performance.mark("commentStart");
135+
136+
let ignored = false;
130137
if (contextNode) {
131138
if (ignoreNodeCallback(contextNode)) {
132-
return undefined;
139+
ignored = true;
140+
}
141+
else {
142+
range = getTextRangeCallback(contextNode) || range;
133143
}
144+
}
134145

135-
range = getTextRangeCallback(contextNode) || range;
146+
let comments: CommentRange[];
147+
if (!ignored) {
148+
comments = getTrailingCommentsOfPositionWorker(range.end);
136149
}
137150

138-
return getTrailingCommentsOfPosition(range.end);
151+
performance.measure("commentTime", "commentStart");
152+
return comments;
139153
}
140154

141155
function getLeadingCommentsOfPosition(pos: number) {
@@ -151,6 +165,13 @@ namespace ts {
151165
}
152166

153167
function getTrailingCommentsOfPosition(pos: number) {
168+
performance.mark("commentStart");
169+
const comments = getTrailingCommentsOfPositionWorker(pos);
170+
performance.measure("commentTime", "commentStart");
171+
return comments;
172+
}
173+
174+
function getTrailingCommentsOfPositionWorker(pos: number) {
154175
if (positionIsSynthesized(pos) || trailingCommentRangePositions[pos]) {
155176
return undefined;
156177
}
@@ -163,6 +184,7 @@ namespace ts {
163184
function emitLeadingComments(range: TextRange, comments: CommentRange[]): void;
164185
function emitLeadingComments(range: TextRange, comments: CommentRange[], contextNode: Node, getTextRangeCallback: (contextNode: Node) => TextRange): void;
165186
function emitLeadingComments(range: TextRange, comments: CommentRange[], contextNode?: Node, getTextRangeCallback?: (contextNode: Node) => TextRange) {
187+
performance.mark("commentStart");
166188
if (comments && comments.length > 0) {
167189
if (contextNode) {
168190
range = getTextRangeCallback(contextNode) || range;
@@ -173,11 +195,14 @@ namespace ts {
173195
// Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
174196
emitComments(currentText, currentLineMap, writer, comments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, writeComment);
175197
}
198+
performance.measure("commentTime", "commentStart");
176199
}
177200

178201
function emitTrailingComments(range: TextRange, comments: CommentRange[]) {
179202
// trailing comments are emitted at space/*trailing comment1 */space/*trailing comment*/
203+
performance.mark("commentStart");
180204
emitComments(currentText, currentLineMap, writer, comments, /*leadingSeparator*/ true, /*trailingSeparator*/ false, newLine, writeComment);
205+
performance.measure("commentTime", "commentStart");
181206
}
182207

183208
function emitLeadingDetachedComments(range: TextRange): void;
@@ -187,7 +212,9 @@ namespace ts {
187212
return;
188213
}
189214

215+
performance.mark("commentStart");
190216
emitDetachedCommentsAndUpdateCommentsInfo(range, /*removeComments*/ false);
217+
performance.measure("commentTime", "commentStart");
191218
}
192219

193220
function emitTrailingDetachedComments(range: TextRange): void;
@@ -264,9 +291,9 @@ namespace ts {
264291
currentText = sourceFile.text;
265292
currentLineMap = getLineStarts(sourceFile);
266293
detachedCommentsInfo = undefined;
267-
consumedCommentRanges = [];
268-
leadingCommentRangePositions = [];
269-
trailingCommentRangePositions = [];
294+
consumedCommentRanges = {};
295+
leadingCommentRangePositions = {};
296+
trailingCommentRangePositions = {};
270297
}
271298

272299
function hasDetachedComments(pos: number) {

src/compiler/core.ts

Lines changed: 77 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,15 +1157,15 @@ namespace ts {
11571157
duration: number;
11581158
}
11591159

1160-
const marks: MarkData[] = [];
1161-
const measures: MeasureData[] = [];
1160+
const markTimestamps: Map<number> = {};
1161+
const markCounts: Map<number> = {};
1162+
const measureDurations: Map<number> = {};
11621163

11631164
let start = now();
11641165
let enabled = false;
11651166

11661167
/** Gets the current timer for performance measurements. */
11671168
export function now() {
1168-
// TODO(rbuckton): Determine if there is a higher-resolution timer we can use.
11691169
return Date.now();
11701170
}
11711171

@@ -1176,103 +1176,110 @@ namespace ts {
11761176
*/
11771177
export function mark(markName: string) {
11781178
if (enabled) {
1179-
marks.push({ markName, timestamp: now() });
1179+
markTimestamps[markName] = now();
1180+
markCounts[markName] = getCount(markName) + 1;
11801181
}
11811182
}
11821183

11831184
/**
1184-
* Adds a performance measurement with the specified name.
1185+
* Gets the number of marks with the specified name.
11851186
*
1186-
* @param measureName The name of the performance measurement.
1187-
* @param startMarkName The name of the starting mark.
1188-
* If provided, the most recent time value of the start mark is used.
1189-
* If not specified, the value is the time that the performance service was
1190-
* initialized or the last time it was reset.
1191-
* @param endMarkName The name of the ending mark.
1192-
* If provided, the most recent time value of the end mark is used.
1193-
* If not specified, the current time is used.
1187+
* @param markName The name of the marks that should be counted.
11941188
*/
1195-
export function measure(measureName: string, startMarkName?: string, endMarkName?: string) {
1189+
export function getCount(markName: string) {
11961190
if (enabled) {
1197-
measures.push({
1198-
measureName,
1199-
startMarkName,
1200-
endMarkName,
1201-
timestamp: now(),
1202-
marksOffset: marks.length
1203-
});
1191+
return getProperty(markCounts, markName) || 0;
12041192
}
1193+
return 0;
12051194
}
12061195

12071196
/**
1208-
* Gets an array of performance measures.
1197+
* Gets the most recent timestamp for the marks with the specified name.
12091198
*
1210-
* @param measureName The name of the measure.
1211-
* If provided, only measures with the provided name are returned.
1212-
* If not specified, all measures are returned since the last time the
1213-
* performance service was reset.
1199+
* @param markName The name of the mark.
12141200
*/
1215-
export function getMeasures(measureName?: string) {
1216-
const result: Measure[] = [];
1217-
for (const measure of measures) {
1218-
if (measureName !== undefined && measureName !== measure.measureName) {
1219-
continue;
1220-
}
1201+
export function getTimestamp(markName: string) {
1202+
if (enabled) {
1203+
return getProperty(markTimestamps, markName) || 0;
1204+
}
1205+
return 0;
1206+
}
12211207

1222-
let startOffset = 0;
1223-
let startTime = start;
1224-
if (measure.startMarkName) {
1225-
const startMarkIndex = getMarkOffset(measure.startMarkName, 0, measure.marksOffset);
1226-
if (startMarkIndex >= 0) {
1227-
startOffset = startMarkIndex;
1228-
startTime = marks[startMarkIndex].timestamp;
1229-
}
1230-
}
1208+
/**
1209+
* Clears performance marks.
1210+
*
1211+
* @param markName The name of the mark whose time values should be cleared. If not
1212+
* specified, all marks will be cleared.
1213+
*/
1214+
export function clearMarks(markName?: string) {
1215+
if (markName === undefined) {
1216+
forEachKey(markTimestamps, clearMark);
1217+
}
1218+
else {
1219+
clearMark(markName);
1220+
}
1221+
}
12311222

1232-
let endTime = measure.timestamp;
1233-
if (measure.endMarkName) {
1234-
const endMarkIndex = getMarkOffset(measure.endMarkName, startOffset, measure.marksOffset);
1235-
if (endMarkIndex >= 0) {
1236-
endTime = marks[endMarkIndex].timestamp;
1237-
}
1238-
}
1223+
function clearMark(markName: string) {
1224+
markTimestamps[markName] = 0;
1225+
markCounts[markName] = 0;
1226+
}
12391227

1228+
/**
1229+
* Adds a performance measurement with the specified name.
1230+
*
1231+
* @param measureName The name of the performance measurement.
1232+
* @param startMarkName The name of the starting mark.
1233+
* If provided, the most recent time value of the start mark is used.
1234+
* If not specified, the value is the time that the performance service was
1235+
* initialized or the last time it was reset.
1236+
* @param endMarkName The name of the ending mark.
1237+
* If provided, the most recent time value of the end mark is used.
1238+
* If not specified, the current time is used.
1239+
*/
1240+
export function measure(measureName: string, startMarkName?: string, endMarkName?: string) {
1241+
if (enabled) {
1242+
const startTime = startMarkName ? getTimestamp(startMarkName) : start;
1243+
const endTime = endMarkName ? getTimestamp(endMarkName) : now();
12401244
const duration = endTime - startTime;
1241-
result.push({
1242-
name: measure.measureName,
1243-
startTime,
1244-
duration
1245-
});
1245+
measureDurations[measureName] = getDuration(measureName) + duration;
12461246
}
1247-
1248-
return result;
12491247
}
12501248

1251-
function getMarkOffset(markName: string, markStart: number, markEnd: number) {
1252-
if (markName === undefined) {
1253-
return -1;
1254-
}
1249+
/**
1250+
* Gets the total duration of all measurements with the supplied name.
1251+
*
1252+
* @param measureName The name of the measure whose durations should be accumulated.
1253+
*/
1254+
export function getDuration(measureName: string) {
1255+
return getProperty(measureDurations, measureName) || 0;
1256+
}
12551257

1256-
if (markStart < 0) {
1257-
markStart = 0;
1258+
/**
1259+
* Clears performance measures.
1260+
*
1261+
* @param measureName The name of the measure whose durations should be cleared. If not
1262+
* specified, all measures will be cleared.
1263+
*/
1264+
export function clearMeasures(measureName?: string) {
1265+
if (measureName === undefined) {
1266+
forEachKey(measureDurations, clearMeasure);
12581267
}
1259-
1260-
for (let i = markEnd - 1; i >= markStart; i--) {
1261-
const mark = marks[i];
1262-
if (mark.markName === markName) {
1263-
return i;
1264-
}
1268+
else {
1269+
clearMeasure(measureName);
12651270
}
1271+
}
12661272

1267-
return -1;
1273+
function clearMeasure(measureName: string) {
1274+
measureDurations[measureName] = 0;
12681275
}
12691276

12701277
/**
12711278
* Resets all marks and measurements in the performance service.
12721279
*/
12731280
export function reset() {
1274-
marks.length = 0;
1275-
measures.length = 0;
1281+
clearMarks();
1282+
clearMeasures();
12761283
start = now();
12771284
}
12781285

src/compiler/printer.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,9 @@ const _super = (function (geti, seti) {
276276
currentFileIdentifiers = node.identifiers;
277277
sourceMap.setSourceFile(node);
278278
comments.setSourceFile(node);
279+
performance.mark("printStart");
279280
emitNodeWithNotificationOption(node, emitWorker);
281+
performance.measure("printTime", "printStart");
280282
return node;
281283
}
282284

0 commit comments

Comments
 (0)