Skip to content

Commit 2ed9789

Browse files
committed
Merge pull request microsoft#8824 from Microsoft/transforms-fixPerformance
[Transforms] Performance fixes
2 parents be41e8d + 82e2531 commit 2ed9789

22 files changed

Lines changed: 727 additions & 343 deletions

src/compiler/binder.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33

44
/* @internal */
55
namespace ts {
6-
export let bindTime = 0;
7-
86
export const enum ModuleInstanceState {
97
NonInstantiated = 0,
108
Instantiated = 1,
@@ -96,9 +94,9 @@ namespace ts {
9694
const binder = createBinder();
9795

9896
export function bindSourceFile(file: SourceFile, options: CompilerOptions) {
99-
const start = new Date().getTime();
97+
const bindStart = performance.mark();
10098
binder(file, options);
101-
bindTime += new Date().getTime() - start;
99+
performance.measure("bindTime", bindStart);
102100
}
103101

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

src/compiler/checker.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ namespace ts {
1414
return node.id;
1515
}
1616

17-
export let checkTime = 0;
18-
1917
export function getSymbolId(symbol: Symbol): number {
2018
if (!symbol.id) {
2119
symbol.id = nextSymbolId;
@@ -16066,11 +16064,11 @@ namespace ts {
1606616064
}
1606716065

1606816066
function checkSourceFile(node: SourceFile) {
16069-
const start = new Date().getTime();
16067+
const checkStart = performance.mark();
1607016068

1607116069
checkSourceFileWorker(node);
1607216070

16073-
checkTime += new Date().getTime() - start;
16071+
performance.measure("checkTime", checkStart);
1607416072
}
1607516073

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

src/compiler/commandLineParser.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ namespace ts {
2727
name: "diagnostics",
2828
type: "boolean",
2929
},
30+
{
31+
name: "extendedDiagnostics",
32+
type: "boolean",
33+
experimental: true,
34+
},
3035
{
3136
name: "emitBOM",
3237
type: "boolean"

src/compiler/comments.ts

Lines changed: 79 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,20 +31,23 @@ 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

39-
return compilerOptions.removeComments
38+
const commentWriter = compilerOptions.removeComments
4039
? createCommentRemovingWriter()
4140
: createCommentPreservingWriter();
4241

42+
return compilerOptions.extendedDiagnostics
43+
? createCommentWriterWithExtendedDiagnostics(commentWriter)
44+
: commentWriter;
45+
4346
function createCommentRemovingWriter(): CommentWriter {
4447
return {
4548
reset,
4649
setSourceFile,
4750
getLeadingComments(range: TextRange, contextNode?: Node, ignoreNodeCallback?: (contextNode: Node) => boolean, getTextRangeCallback?: (contextNode: Node) => TextRange): CommentRange[] { return undefined; },
48-
getLeadingCommentsOfPosition(pos: number): CommentRange[] { return undefined; },
4951
getTrailingComments(range: TextRange, contextNode?: Node, ignoreNodeCallback?: (contextNode: Node) => boolean, getTextRangeCallback?: (contextNode: Node) => TextRange): CommentRange[] { return undefined; },
5052
getTrailingCommentsOfPosition(pos: number): CommentRange[] { return undefined; },
5153
emitLeadingComments(range: TextRange, comments: CommentRange[], contextNode?: Node, getTextRangeCallback?: (contextNode: Node) => TextRange): void { },
@@ -69,7 +71,6 @@ namespace ts {
6971
reset,
7072
setSourceFile,
7173
getLeadingComments,
72-
getLeadingCommentsOfPosition,
7374
getTrailingComments,
7475
getTrailingCommentsOfPosition,
7576
emitLeadingComments,
@@ -100,11 +101,10 @@ namespace ts {
100101
return filter(getLeadingCommentsOfPosition(0), isTripleSlashComment);
101102
}
102103

103-
return undefined;
104+
return;
104105
}
105106
}
106107

107-
108108
return getLeadingCommentsOfPosition(range.pos);
109109
}
110110

@@ -127,15 +127,21 @@ namespace ts {
127127
function getTrailingComments(range: TextRange): CommentRange[];
128128
function getTrailingComments(range: TextRange, contextNode: Node, ignoreNodeCallback: (contextNode: Node) => boolean, getTextRangeCallback: (contextNode: Node) => TextRange): CommentRange[];
129129
function getTrailingComments(range: TextRange, contextNode?: Node, ignoreNodeCallback?: (contextNode: Node) => boolean, getTextRangeCallback?: (contextNode: Node) => TextRange) {
130+
let ignored = false;
130131
if (contextNode) {
131132
if (ignoreNodeCallback(contextNode)) {
132-
return undefined;
133+
ignored = true;
134+
}
135+
else {
136+
range = getTextRangeCallback(contextNode) || range;
133137
}
134-
135-
range = getTextRangeCallback(contextNode) || range;
136138
}
137139

138-
return getTrailingCommentsOfPosition(range.end);
140+
let comments: CommentRange[];
141+
if (!ignored) {
142+
comments = getTrailingCommentsOfPosition(range.end);
143+
}
144+
return comments;
139145
}
140146

141147
function getLeadingCommentsOfPosition(pos: number) {
@@ -249,6 +255,63 @@ namespace ts {
249255
}
250256
}
251257

258+
function createCommentWriterWithExtendedDiagnostics(writer: CommentWriter): CommentWriter {
259+
const {
260+
reset,
261+
setSourceFile,
262+
getLeadingComments,
263+
getTrailingComments,
264+
getTrailingCommentsOfPosition,
265+
emitLeadingComments,
266+
emitTrailingComments,
267+
emitLeadingDetachedComments,
268+
emitTrailingDetachedComments
269+
} = writer;
270+
271+
return {
272+
reset,
273+
setSourceFile,
274+
getLeadingComments(range: TextRange, contextNode?: Node, ignoreNodeCallback?: (contextNode: Node) => boolean, getTextRangeCallback?: (contextNode: Node) => TextRange): CommentRange[] {
275+
const commentStart = performance.mark();
276+
const comments = getLeadingComments(range, contextNode, ignoreNodeCallback, getTextRangeCallback);
277+
performance.measure("commentTime", commentStart);
278+
return comments;
279+
},
280+
getTrailingComments(range: TextRange, contextNode?: Node, ignoreNodeCallback?: (contextNode: Node) => boolean, getTextRangeCallback?: (contextNode: Node) => TextRange): CommentRange[] {
281+
const commentStart = performance.mark();
282+
const comments = getTrailingComments(range, contextNode, ignoreNodeCallback, getTextRangeCallback);
283+
performance.measure("commentTime", commentStart);
284+
return comments;
285+
},
286+
getTrailingCommentsOfPosition(pos: number): CommentRange[] {
287+
const commentStart = performance.mark();
288+
const comments = getTrailingCommentsOfPosition(pos);
289+
performance.measure("commentTime", commentStart);
290+
return comments;
291+
},
292+
emitLeadingComments(range: TextRange, comments: CommentRange[], contextNode?: Node, getTextRangeCallback?: (contextNode: Node) => TextRange): void {
293+
const commentStart = performance.mark();
294+
emitLeadingComments(range, comments, contextNode, getTextRangeCallback);
295+
performance.measure("commentTime", commentStart);
296+
},
297+
emitTrailingComments(range: TextRange, comments: CommentRange[]): void {
298+
const commentStart = performance.mark();
299+
emitLeadingComments(range, comments);
300+
performance.measure("commentTime", commentStart);
301+
},
302+
emitLeadingDetachedComments(range: TextRange, contextNode?: Node, ignoreNodeCallback?: (contextNode: Node) => boolean): void {
303+
const commentStart = performance.mark();
304+
emitLeadingDetachedComments(range, contextNode, ignoreNodeCallback);
305+
performance.measure("commentTime", commentStart);
306+
},
307+
emitTrailingDetachedComments(range: TextRange, contextNode?: Node, ignoreNodeCallback?: (contextNode: Node) => boolean): void {
308+
const commentStart = performance.mark();
309+
emitTrailingDetachedComments(range, contextNode, ignoreNodeCallback);
310+
performance.measure("commentTime", commentStart);
311+
}
312+
};
313+
}
314+
252315
function reset() {
253316
currentSourceFile = undefined;
254317
currentText = undefined;
@@ -264,9 +327,9 @@ namespace ts {
264327
currentText = sourceFile.text;
265328
currentLineMap = getLineStarts(sourceFile);
266329
detachedCommentsInfo = undefined;
267-
consumedCommentRanges = [];
268-
leadingCommentRangePositions = [];
269-
trailingCommentRangePositions = [];
330+
consumedCommentRanges = {};
331+
leadingCommentRangePositions = {};
332+
trailingCommentRangePositions = {};
270333
}
271334

272335
function hasDetachedComments(pos: number) {

src/compiler/core.ts

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,7 @@ namespace ts {
10491049
}
10501050

10511051
function Node(kind: SyntaxKind, pos: number, end: number) {
1052+
this.id = 0;
10521053
this.kind = kind;
10531054
this.pos = pos;
10541055
this.end = end;
@@ -1058,6 +1059,7 @@ namespace ts {
10581059
this.excludeTransformFlags = TransformFlags.None;
10591060
this.parent = undefined;
10601061
this.original = undefined;
1062+
this.transformId = 0;
10611063
}
10621064

10631065
export let objectAllocator: ObjectAllocator = {
@@ -1118,6 +1120,18 @@ namespace ts {
11181120
}
11191121
}
11201122

1123+
export function getEnvironmentVariable(name: string, host?: CompilerHost) {
1124+
if (host && host.getEnvironmentVariable) {
1125+
return host.getEnvironmentVariable(name);
1126+
}
1127+
1128+
if (sys && sys.getEnvironmentVariable) {
1129+
return sys.getEnvironmentVariable(name);
1130+
}
1131+
1132+
return "";
1133+
}
1134+
11211135
export function copyListRemovingItem<T>(item: T, list: T[]) {
11221136
const copiedList: T[] = [];
11231137
for (const e of list) {
@@ -1134,4 +1148,80 @@ namespace ts {
11341148
: ((fileName) => fileName.toLowerCase());
11351149
}
11361150

1151+
/** Performance measurements for the compiler. */
1152+
/*@internal*/
1153+
export namespace performance {
1154+
let counters: Map<number>;
1155+
let measures: Map<number>;
1156+
1157+
/**
1158+
* Increments a counter with the specified name.
1159+
*
1160+
* @param counterName The name of the counter.
1161+
*/
1162+
export function increment(counterName: string) {
1163+
if (counters) {
1164+
counters[counterName] = (getProperty(counters, counterName) || 0) + 1;
1165+
}
1166+
}
1167+
1168+
/**
1169+
* Gets the value of the counter with the specified name.
1170+
*
1171+
* @param counterName The name of the counter.
1172+
*/
1173+
export function getCount(counterName: string) {
1174+
return counters && getProperty(counters, counterName) || 0;
1175+
}
1176+
1177+
/**
1178+
* Marks the start of a performance measurement.
1179+
*/
1180+
export function mark() {
1181+
return measures ? Date.now() : 0;
1182+
}
1183+
1184+
/**
1185+
* Adds a performance measurement with the specified name.
1186+
*
1187+
* @param measureName The name of the performance measurement.
1188+
* @param marker The timestamp of the starting mark.
1189+
*/
1190+
export function measure(measureName: string, marker: number) {
1191+
if (measures) {
1192+
measures[measureName] = (getProperty(measures, measureName) || 0) + (mark() - marker);
1193+
}
1194+
}
1195+
1196+
/**
1197+
* Gets the total duration of all measurements with the supplied name.
1198+
*
1199+
* @param measureName The name of the measure whose durations should be accumulated.
1200+
*/
1201+
export function getDuration(measureName: string) {
1202+
return measures && getProperty(measures, measureName) || 0;
1203+
}
1204+
1205+
/** Enables (and resets) performance measurements for the compiler. */
1206+
export function enable() {
1207+
counters = { };
1208+
measures = {
1209+
programTime: 0,
1210+
parseTime: 0,
1211+
bindTime: 0,
1212+
emitTime: 0,
1213+
ioReadTime: 0,
1214+
ioWriteTime: 0,
1215+
printTime: 0,
1216+
commentTime: 0,
1217+
sourceMapTime: 0
1218+
};
1219+
}
1220+
1221+
/** Disables (and clears) performance measurements for the compiler. */
1222+
export function disable() {
1223+
counters = undefined;
1224+
measures = undefined;
1225+
}
1226+
}
11371227
}

src/compiler/emitter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
524524
const writer = createTextWriter(newLine);
525525
const { write, writeTextOfNode, writeLine, increaseIndent, decreaseIndent } = writer;
526526

527-
let sourceMap = compilerOptions.sourceMap || compilerOptions.inlineSourceMap ? createSourceMapWriter(host, writer) : getNullSourceMapWriter();
527+
let sourceMap = createSourceMapWriter(host, writer);
528528
let { setSourceFile, emitStart, emitEnd, emitPos } = sourceMap;
529529

530530
let currentSourceFile: SourceFile;

0 commit comments

Comments
 (0)