@@ -11,6 +11,14 @@ import { loadConfigFile } from '../dist/loadConfigFile.js';
11
11
import { rollup } from '../dist/rollup.js' ;
12
12
import { findConfigFileName } from './find-config.js' ;
13
13
14
+ /**
15
+ * @typedef {Record<string,{memory:number,time:number}> } PersistedTimings
16
+ */
17
+
18
+ /**
19
+ * @typedef {Record<string, [number, number, number][]> } AccumulatedTimings
20
+ */
21
+
14
22
const initialDirectory = cwd ( ) ;
15
23
const targetDirectory = fileURLToPath ( new URL ( '../perf' , import . meta. url ) . href ) ;
16
24
const perfFile = fileURLToPath ( new URL ( '../perf/rollup.perf.json' , import . meta. url ) . href ) ;
@@ -51,6 +59,12 @@ console.info(
51
59
52
60
await calculatePrintAndPersistTimings ( configs . options [ 0 ] , await getExistingTimings ( ) ) ;
53
61
62
+ /**
63
+ * @param {number[] } times
64
+ * @param {number } runs
65
+ * @param {number } discarded
66
+ * @return {number }
67
+ */
54
68
function getSingleAverage ( times , runs , discarded ) {
55
69
const actualDiscarded = Math . min ( discarded , runs - 1 ) ;
56
70
return (
@@ -63,7 +77,16 @@ function getSingleAverage(times, runs, discarded) {
63
77
) ;
64
78
}
65
79
80
+ /**
81
+ * @param {AccumulatedTimings } accumulatedMeasurements
82
+ * @param {number } runs
83
+ * @param {number } discarded
84
+ * @return {PersistedTimings }
85
+ */
66
86
function getAverage ( accumulatedMeasurements , runs , discarded ) {
87
+ /**
88
+ * @type {PersistedTimings }
89
+ */
67
90
const average = { } ;
68
91
for ( const label of Object . keys ( accumulatedMeasurements ) ) {
69
92
average [ label ] = {
@@ -82,50 +105,80 @@ function getAverage(accumulatedMeasurements, runs, discarded) {
82
105
return average ;
83
106
}
84
107
108
+ /**
109
+ * @param {import('rollup').MergedRollupOptions } config
110
+ * @param {PersistedTimings } existingTimings
111
+ * @return {Promise<void> }
112
+ */
85
113
async function calculatePrintAndPersistTimings ( config , existingTimings ) {
86
- const timings = await buildAndGetTimings ( config ) ;
87
- for ( const label of Object . keys ( timings ) ) {
88
- timings [ label ] = [ timings [ label ] ] ;
114
+ const serializedTimings = await buildAndGetTimings ( config ) ;
115
+ /**
116
+ * @type {Record<string, [number, number, number][]> }
117
+ */
118
+ const accumulatedTimings = { } ;
119
+ for ( const label of Object . keys ( serializedTimings ) ) {
120
+ accumulatedTimings [ label ] = [ serializedTimings [ label ] ] ;
89
121
}
90
122
for ( let currentRun = 1 ; currentRun < numberOfRunsToAverage ; currentRun ++ ) {
91
123
const numberOfLinesToClear = printMeasurements (
92
- getAverage ( timings , currentRun , numberOfDiscardedResults ) ,
124
+ getAverage ( accumulatedTimings , currentRun , numberOfDiscardedResults ) ,
93
125
existingTimings ,
94
126
/ ^ # /
95
127
) ;
96
128
console . info ( `Completed run ${ currentRun } .` ) ;
97
129
const currentTimings = await buildAndGetTimings ( config ) ;
98
130
clearLines ( numberOfLinesToClear ) ;
99
- for ( const label of Object . keys ( timings ) ) {
131
+ for ( const label of Object . keys ( accumulatedTimings ) ) {
100
132
if ( currentTimings . hasOwnProperty ( label ) ) {
101
- timings [ label ] . push ( currentTimings [ label ] ) ;
133
+ accumulatedTimings [ label ] . push ( currentTimings [ label ] ) ;
102
134
} else {
103
- delete timings [ label ] ;
135
+ delete accumulatedTimings [ label ] ;
104
136
}
105
137
}
106
138
}
107
- const averageTimings = getAverage ( timings , numberOfRunsToAverage , numberOfDiscardedResults ) ;
139
+ const averageTimings = getAverage (
140
+ accumulatedTimings ,
141
+ numberOfRunsToAverage ,
142
+ numberOfDiscardedResults
143
+ ) ;
108
144
printMeasurements ( averageTimings , existingTimings ) ;
109
- if ( Object . keys ( existingTimings ) . length === 0 ) persistTimings ( averageTimings ) ;
145
+ if ( Object . keys ( existingTimings ) . length === 0 ) {
146
+ persistTimings ( averageTimings ) ;
147
+ }
110
148
}
111
149
150
+ /**
151
+ * @param {import('rollup').MergedRollupOptions } config
152
+ * @return {Promise<import('rollup').SerializedTimings> }
153
+ */
112
154
async function buildAndGetTimings ( config ) {
113
155
config . perf = true ;
114
- if ( Array . isArray ( config . output ) ) {
115
- config . output = config . output [ 0 ] ;
116
- }
156
+ const output = Array . isArray ( config . output ) ? config . output [ 0 ] : config . output ;
157
+ // @ts -expect-error garbage collection may not be enabled
117
158
gc ( ) ;
118
159
chdir ( targetDirectory ) ;
119
160
const bundle = await rollup ( config ) ;
120
161
chdir ( initialDirectory ) ;
121
- await bundle . generate ( config . output ) ;
162
+ await bundle . generate ( output ) ;
163
+ if ( ! bundle . getTimings ) {
164
+ throw new Error ( 'Timings not found in the bundle.' ) ;
165
+ }
122
166
return bundle . getTimings ( ) ;
123
167
}
124
168
169
+ /**
170
+ * @param {PersistedTimings } average
171
+ * @param {PersistedTimings } existingAverage
172
+ * @param {RegExp } filter
173
+ * @return {number }
174
+ */
125
175
function printMeasurements ( average , existingAverage , filter = / .* / ) {
126
176
const printedLabels = Object . keys ( average ) . filter ( label => filter . test ( label ) ) ;
127
177
console . info ( '' ) ;
128
178
for ( const label of printedLabels ) {
179
+ /**
180
+ * @type {function(string): string }
181
+ */
129
182
let color = identity ;
130
183
if ( label [ 0 ] === '#' ) {
131
184
color = bold ;
@@ -148,10 +201,16 @@ function printMeasurements(average, existingAverage, filter = /.*/) {
148
201
return printedLabels . length + 2 ;
149
202
}
150
203
204
+ /**
205
+ * @param {number } numberOfLines
206
+ */
151
207
function clearLines ( numberOfLines ) {
152
208
console . info ( '\u001B[A' + '\u001B[2K\u001B[A' . repeat ( numberOfLines ) ) ;
153
209
}
154
210
211
+ /**
212
+ * @return {PersistedTimings }
213
+ */
155
214
function getExistingTimings ( ) {
156
215
try {
157
216
const timings = JSON . parse ( readFileSync ( perfFile , 'utf8' ) ) ;
@@ -164,6 +223,9 @@ function getExistingTimings() {
164
223
}
165
224
}
166
225
226
+ /**
227
+ * @param {PersistedTimings } timings
228
+ */
167
229
function persistTimings ( timings ) {
168
230
try {
169
231
writeFileSync ( perfFile , JSON . stringify ( timings , null , 2 ) , 'utf8' ) ;
@@ -174,7 +236,15 @@ function persistTimings(timings) {
174
236
}
175
237
}
176
238
239
+ /**
240
+ * @param {number } currentTime
241
+ * @param {number } persistedTime
242
+ * @return {string }
243
+ */
177
244
function getFormattedTime ( currentTime , persistedTime = currentTime ) {
245
+ /**
246
+ * @type {function(string): string }
247
+ */
178
248
let color = identity ,
179
249
formattedTime = `${ currentTime . toFixed ( 0 ) } ms` ;
180
250
const absoluteDeviation = Math . abs ( currentTime - persistedTime ) ;
@@ -191,7 +261,15 @@ function getFormattedTime(currentTime, persistedTime = currentTime) {
191
261
return color ( formattedTime ) ;
192
262
}
193
263
264
+ /**
265
+ * @param {number } currentMemory
266
+ * @param {number } persistedMemory
267
+ * @return {string }
268
+ */
194
269
function getFormattedMemory ( currentMemory , persistedMemory = currentMemory ) {
270
+ /**
271
+ * @type {function(string): string }
272
+ */
195
273
let color = identity ,
196
274
formattedMemory = prettyBytes ( currentMemory ) ;
197
275
const absoluteDeviation = Math . abs ( currentMemory - persistedMemory ) ;
@@ -204,6 +282,11 @@ function getFormattedMemory(currentMemory, persistedMemory = currentMemory) {
204
282
return color ( formattedMemory ) ;
205
283
}
206
284
285
+ /**
286
+ * @template T
287
+ * @param {T } x
288
+ * @returns {T }
289
+ */
207
290
function identity ( x ) {
208
291
return x ;
209
292
}
0 commit comments