2
2
/** Performance measurements for the compiler. */
3
3
namespace ts . performance {
4
4
let perfHooks : PerformanceHooks | undefined ;
5
- let perfObserver : PerformanceObserver | undefined ;
6
5
// when set, indicates the implementation of `Performance` to use for user timing.
7
6
// when unset, indicates user timing is unavailable or disabled.
8
7
let performanceImpl : Performance | undefined ;
@@ -41,6 +40,10 @@ namespace ts.performance {
41
40
}
42
41
43
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 > ( ) ;
44
47
const counts = new Map < string , number > ( ) ;
45
48
const durations = new Map < string , number > ( ) ;
46
49
@@ -50,7 +53,12 @@ namespace ts.performance {
50
53
* @param markName The name of the mark.
51
54
*/
52
55
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
+ }
54
62
}
55
63
56
64
/**
@@ -63,7 +71,13 @@ namespace ts.performance {
63
71
* used.
64
72
*/
65
73
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
+ }
67
81
}
68
82
69
83
/**
@@ -97,35 +111,36 @@ namespace ts.performance {
97
111
* Indicates whether the performance API is enabled.
98
112
*/
99
113
export function isEnabled ( ) {
100
- return ! ! performanceImpl ;
114
+ return enabled ;
101
115
}
102
116
103
117
/** 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 ;
106
121
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
+ }
111
132
}
112
133
return true ;
113
134
}
114
135
115
136
/** Disables performance measurements for the compiler. */
116
137
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 ;
129
144
}
130
145
}
131
146
}
0 commit comments