22/** Performance measurements for the compiler. */
33namespace ts . performance {
44 let perfHooks : PerformanceHooks | undefined ;
5- let perfObserver : PerformanceObserver | undefined ;
65 // when set, indicates the implementation of `Performance` to use for user timing.
76 // when unset, indicates user timing is unavailable or disabled.
87 let performanceImpl : Performance | undefined ;
@@ -41,6 +40,10 @@ namespace ts.performance {
4140 }
4241
4342 export const nullTimer : Timer = { enter : noop , exit : noop } ;
43+
44+ let enabled = false ;
45+ let timeorigin = timestamp ( ) ;
46+ const marks = new Map < string , number > ( ) ;
4447 const counts = new Map < string , number > ( ) ;
4548 const durations = new Map < string , number > ( ) ;
4649
@@ -50,7 +53,12 @@ namespace ts.performance {
5053 * @param markName The name of the mark.
5154 */
5255 export function mark ( markName : string ) {
53- performanceImpl ?. mark ( markName ) ;
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 ) ;
61+ }
5462 }
5563
5664 /**
@@ -63,7 +71,13 @@ namespace ts.performance {
6371 * used.
6472 */
6573 export function measure ( measureName : string , startMarkName ?: string , endMarkName ?: string ) {
66- performanceImpl ?. measure ( measureName , startMarkName , endMarkName ) ;
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 ) ;
80+ }
6781 }
6882
6983 /**
@@ -97,35 +111,36 @@ namespace ts.performance {
97111 * Indicates whether the performance API is enabled.
98112 */
99113 export function isEnabled ( ) {
100- return ! ! performanceImpl ;
114+ return enabled ;
101115 }
102116
103117 /** Enables (and resets) performance measurements for the compiler. */
104- export function enable ( ) {
105- if ( ! performanceImpl ) {
118+ export function enable ( system : System = sys ) {
119+ if ( ! enabled ) {
120+ enabled = true ;
106121 perfHooks ||= tryGetNativePerformanceHooks ( ) ;
107- if ( ! perfHooks ) return false ;
108- perfObserver ||= new perfHooks . PerformanceObserver ( updateStatisticsFromList ) ;
109- perfObserver . observe ( { entryTypes : [ "mark" , "measure" ] } ) ;
110- performanceImpl = perfHooks . performance ;
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 ;
130+ }
131+ }
111132 }
112133 return true ;
113134 }
114135
115136 /** Disables performance measurements for the compiler. */
116137 export function disable ( ) {
117- perfObserver ?. disconnect ( ) ;
118- performanceImpl = undefined ;
119- counts . clear ( ) ;
120- durations . clear ( ) ;
121- }
122-
123- function updateStatisticsFromList ( list : PerformanceObserverEntryList ) {
124- for ( const mark of list . getEntriesByType ( "mark" ) ) {
125- counts . set ( mark . name , ( counts . get ( mark . name ) || 0 ) + 1 ) ;
126- }
127- for ( const measure of list . getEntriesByType ( "measure" ) ) {
128- durations . set ( measure . name , ( durations . get ( measure . name ) || 0 ) + measure . duration ) ;
138+ if ( enabled ) {
139+ marks . clear ( ) ;
140+ counts . clear ( ) ;
141+ durations . clear ( ) ;
142+ performanceImpl = undefined ;
143+ enabled = false ;
129144 }
130145 }
131146}
0 commit comments