Integrate feedback from @mihailik to performance framework (#9845)

* Integrate feedback from @mihailik

* Rons feedback, explicitly include in new tsconfigs
This commit is contained in:
Wesley Wigham
2016-07-20 15:42:29 -07:00
committed by GitHub
parent 80db0f2f16
commit 729464dc23
5 changed files with 126 additions and 122 deletions

View File

@@ -1,107 +1,109 @@
/*@internal*/
namespace ts {
declare const performance: { now?(): number } | undefined;
/** Gets a timestamp with (at least) ms resolution */
export const timestamp = typeof performance !== "undefined" && performance.now ? performance.now : Date.now ? Date.now : () => +(new Date());
}
/*@internal*/
namespace ts.performance {
/** Performance measurements for the compiler. */
export namespace performance {
declare const onProfilerEvent: { (markName: string): void; profiler: boolean; };
declare const performance: { now?(): number } | undefined;
let profilerEvent: (markName: string) => void;
let markInternal: () => number;
let counters: Map<number>;
let measures: Map<number>;
declare const onProfilerEvent: { (markName: string): void; profiler: boolean; };
let profilerEvent: (markName: string) => void;
let counters: Map<number>;
let measures: Map<number>;
/**
* Emit a performance event if ts-profiler is connected. This is primarily used
* to generate heap snapshots.
*
* @param eventName A name for the event.
*/
export function emit(eventName: string) {
if (profilerEvent) {
profilerEvent(eventName);
}
}
/**
* Increments a counter with the specified name.
*
* @param counterName The name of the counter.
*/
export function increment(counterName: string) {
if (counters) {
counters[counterName] = (getProperty(counters, counterName) || 0) + 1;
}
}
/**
* Gets the value of the counter with the specified name.
*
* @param counterName The name of the counter.
*/
export function getCount(counterName: string) {
return counters && getProperty(counters, counterName) || 0;
}
/**
* Marks the start of a performance measurement.
*/
export function mark() {
return measures ? markInternal() : 0;
}
/**
* Adds a performance measurement with the specified name.
*
* @param measureName The name of the performance measurement.
* @param marker The timestamp of the starting mark.
*/
export function measure(measureName: string, marker: number) {
if (measures) {
measures[measureName] = (getProperty(measures, measureName) || 0) + (Date.now() - marker);
}
}
/**
* Iterate over each measure, performing some action
*
* @param cb The action to perform for each measure
*/
export function forEachMeasure(cb: (measureName: string, duration: number) => void) {
return forEachKey(measures, key => cb(key, measures[key]));
}
/**
* Gets the total duration of all measurements with the supplied name.
*
* @param measureName The name of the measure whose durations should be accumulated.
*/
export function getDuration(measureName: string) {
return measures && getProperty(measures, measureName) || 0;
}
/** Enables (and resets) performance measurements for the compiler. */
export function enable() {
counters = { };
measures = {
"I/O Read": 0,
"I/O Write": 0,
"Program": 0,
"Parse": 0,
"Bind": 0,
"Check": 0,
"Emit": 0,
};
profilerEvent = typeof onProfilerEvent === "function" && onProfilerEvent.profiler === true
? onProfilerEvent
: undefined;
markInternal = performance && performance.now ? performance.now : Date.now ? Date.now : () => new Date().getTime();
}
/** Disables (and clears) performance measurements for the compiler. */
export function disable() {
counters = undefined;
measures = undefined;
profilerEvent = undefined;
/**
* Emit a performance event if ts-profiler is connected. This is primarily used
* to generate heap snapshots.
*
* @param eventName A name for the event.
*/
export function emit(eventName: string) {
if (profilerEvent) {
profilerEvent(eventName);
}
}
/**
* Increments a counter with the specified name.
*
* @param counterName The name of the counter.
*/
export function increment(counterName: string) {
if (counters) {
counters[counterName] = (getProperty(counters, counterName) || 0) + 1;
}
}
/**
* Gets the value of the counter with the specified name.
*
* @param counterName The name of the counter.
*/
export function getCount(counterName: string) {
return counters && getProperty(counters, counterName) || 0;
}
/**
* Marks the start of a performance measurement.
*/
export function mark() {
return measures ? timestamp() : 0;
}
/**
* Adds a performance measurement with the specified name.
*
* @param measureName The name of the performance measurement.
* @param marker The timestamp of the starting mark.
*/
export function measure(measureName: string, marker: number) {
if (measures) {
measures[measureName] = (getProperty(measures, measureName) || 0) + (timestamp() - marker);
}
}
/**
* Iterate over each measure, performing some action
*
* @param cb The action to perform for each measure
*/
export function forEachMeasure(cb: (measureName: string, duration: number) => void) {
return forEachKey(measures, key => cb(key, measures[key]));
}
/**
* Gets the total duration of all measurements with the supplied name.
*
* @param measureName The name of the measure whose durations should be accumulated.
*/
export function getDuration(measureName: string) {
return measures && getProperty(measures, measureName) || 0;
}
/** Enables (and resets) performance measurements for the compiler. */
export function enable() {
counters = { };
measures = {
"I/O Read": 0,
"I/O Write": 0,
"Program": 0,
"Parse": 0,
"Bind": 0,
"Check": 0,
"Emit": 0,
};
profilerEvent = typeof onProfilerEvent === "function" && onProfilerEvent.profiler === true
? onProfilerEvent
: undefined;
}
/** Disables (and clears) performance measurements for the compiler. */
export function disable() {
counters = undefined;
measures = undefined;
profilerEvent = undefined;
}
}

View File

@@ -14,6 +14,7 @@
},
"files": [
"../compiler/core.ts",
"../compiler/performance.ts",
"../compiler/sys.ts",
"../compiler/types.ts",
"../compiler/scanner.ts",

View File

@@ -434,7 +434,7 @@ namespace ts {
}
}
IdentifierObject.prototype.kind = SyntaxKind.Identifier;
class SymbolObject implements Symbol {
flags: SymbolFlags;
name: string;
@@ -3349,14 +3349,14 @@ namespace ts {
let isJsDocTagName = false;
let start = new Date().getTime();
let start = timestamp();
const currentToken = getTokenAtPosition(sourceFile, position);
log("getCompletionData: Get current token: " + (new Date().getTime() - start));
log("getCompletionData: Get current token: " + (timestamp() - start));
start = new Date().getTime();
start = timestamp();
// Completion not allowed inside comments, bail out if this is the case
const insideComment = isInsideComment(sourceFile, currentToken, position);
log("getCompletionData: Is inside comment: " + (new Date().getTime() - start));
log("getCompletionData: Is inside comment: " + (timestamp() - start));
if (insideComment) {
// The current position is next to the '@' sign, when no tag name being provided yet.
@@ -3399,9 +3399,9 @@ namespace ts {
}
}
start = new Date().getTime();
start = timestamp();
const previousToken = findPrecedingToken(position, sourceFile);
log("getCompletionData: Get previous token 1: " + (new Date().getTime() - start));
log("getCompletionData: Get previous token 1: " + (timestamp() - start));
// The decision to provide completion depends on the contextToken, which is determined through the previousToken.
// Note: 'previousToken' (and thus 'contextToken') can be undefined if we are the beginning of the file
@@ -3410,9 +3410,9 @@ namespace ts {
// Check if the caret is at the end of an identifier; this is a partial identifier that we want to complete: e.g. a.toS|
// Skip this partial identifier and adjust the contextToken to the token that precedes it.
if (contextToken && position <= contextToken.end && isWord(contextToken.kind)) {
const start = new Date().getTime();
const start = timestamp();
contextToken = findPrecedingToken(contextToken.getFullStart(), sourceFile);
log("getCompletionData: Get previous token 2: " + (new Date().getTime() - start));
log("getCompletionData: Get previous token 2: " + (timestamp() - start));
}
// Find the node where completion is requested on.
@@ -3459,7 +3459,7 @@ namespace ts {
}
}
const semanticStart = new Date().getTime();
const semanticStart = timestamp();
let isMemberCompletion: boolean;
let isNewIdentifierLocation: boolean;
let symbols: Symbol[] = [];
@@ -3497,7 +3497,7 @@ namespace ts {
}
}
log("getCompletionData: Semantic work: " + (new Date().getTime() - semanticStart));
log("getCompletionData: Semantic work: " + (timestamp() - semanticStart));
return { symbols, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), isJsDocTagName };
@@ -3641,12 +3641,12 @@ namespace ts {
}
function isCompletionListBlocker(contextToken: Node): boolean {
const start = new Date().getTime();
const start = timestamp();
const result = isInStringOrRegularExpressionOrTemplateLiteral(contextToken) ||
isSolelyIdentifierDefinitionLocation(contextToken) ||
isDotOfNumericLiteral(contextToken) ||
isInJsxText(contextToken);
log("getCompletionsAtPosition: isCompletionListBlocker: " + (new Date().getTime() - start));
log("getCompletionsAtPosition: isCompletionListBlocker: " + (timestamp() - start));
return result;
}
@@ -4299,7 +4299,7 @@ namespace ts {
}
function getCompletionEntriesFromSymbols(symbols: Symbol[], entries: CompletionEntry[], location: Node, performCharacterChecks: boolean): Map<string> {
const start = new Date().getTime();
const start = timestamp();
const uniqueNames: Map<string> = {};
if (symbols) {
for (const symbol of symbols) {
@@ -4314,7 +4314,7 @@ namespace ts {
}
}
log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (new Date().getTime() - start));
log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (timestamp() - start));
return uniqueNames;
}
@@ -7735,14 +7735,14 @@ namespace ts {
}
function getIndentationAtPosition(fileName: string, position: number, editorOptions: EditorOptions) {
let start = new Date().getTime();
let start = timestamp();
const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
log("getIndentationAtPosition: getCurrentSourceFile: " + (new Date().getTime() - start));
log("getIndentationAtPosition: getCurrentSourceFile: " + (timestamp() - start));
start = new Date().getTime();
start = timestamp();
const result = formatting.SmartIndenter.getIndentation(position, sourceFile, editorOptions);
log("getIndentationAtPosition: computeIndentation : " + (new Date().getTime() - start));
log("getIndentationAtPosition: computeIndentation : " + (timestamp() - start));
return result;
}

View File

@@ -423,7 +423,7 @@ namespace ts {
}
public isCancellationRequested(): boolean {
const time = Date.now();
const time = timestamp();
const duration = Math.abs(time - this.lastCancellationCheckTime);
if (duration > 10) {
// Check no more than once every 10 ms.
@@ -498,13 +498,13 @@ namespace ts {
let start: number;
if (logPerformance) {
logger.log(actionDescription);
start = Date.now();
start = timestamp();
}
const result = action();
if (logPerformance) {
const end = Date.now();
const end = timestamp();
logger.log(`${actionDescription} completed in ${end - start} msec`);
if (typeof result === "string") {
let str = result;

View File

@@ -13,6 +13,7 @@
},
"files": [
"../compiler/core.ts",
"../compiler/performance.ts",
"../compiler/sys.ts",
"../compiler/types.ts",
"../compiler/scanner.ts",