@@ -137,5 +137,51 @@ for (const filename of files) {
137137 console . log ( ` ratio: ${ ( tpTime / smolTime ) . toFixed ( 1 ) } x slower` ) ;
138138}
139139
140+ // ── Phase 4: Stringify CPU profile ──────────────────────────────────────────
141+ console . log ( '\n\n' ) ;
142+ console . log ( '═' . repeat ( 80 ) ) ;
143+ console . log ( ' V8 CPU PROFILE — stringify hot paths' ) ;
144+ console . log ( '═' . repeat ( 80 ) ) ;
145+
146+ const sfData = readFileSync ( join ( benchDir , '0C-scaling-table-inline-1000.toml' ) , 'utf8' ) ;
147+ const sfObj = smolToml . parse ( sfData ) ;
148+
149+ const sfSession = new Session ( ) ;
150+ sfSession . connect ( ) ;
151+
152+ await sfSession . post ( 'Profiler.enable' ) ;
153+ await sfSession . post ( 'Profiler.start' ) ;
154+
155+ console . log ( '\n Profiling stringify (2000 iterations)...' ) ;
156+ for ( let i = 0 ; i < 2000 ; i ++ ) tomlPatch . stringify ( sfObj ) ;
157+
158+ const { profile : sfProfile } = await sfSession . post ( 'Profiler.stop' ) ;
159+
160+ const sfTimes = new Map ( ) ;
161+ for ( const node of sfProfile . nodes ) {
162+ const { functionName, url, lineNumber } = node . callFrame ;
163+ if ( ! url . includes ( 'toml-patch' ) ) continue ;
164+ const hitCount = node . hitCount || 0 ;
165+ if ( hitCount === 0 ) continue ;
166+ const fn = functionName || '(anonymous)' ;
167+ const key = `${ fn } (${ basename ( url ) } :${ lineNumber + 1 } )` ;
168+ sfTimes . set ( key , ( sfTimes . get ( key ) || 0 ) + hitCount ) ;
169+ }
170+
171+ const sfSorted = [ ...sfTimes . entries ( ) ] . sort ( ( a , b ) => b [ 1 ] - a [ 1 ] ) ;
172+ const sfTotal = sfSorted . reduce ( ( sum , [ , h ] ) => sum + h , 0 ) ;
173+
174+ console . log ( `\n Top functions by CPU self-time (${ sfTotal } total samples):\n` ) ;
175+ console . log ( ` ${ 'Function' . padEnd ( 58 ) } Samples %` ) ;
176+ console . log ( ' ' + '─' . repeat ( 74 ) ) ;
177+ for ( const [ fn , hits ] of sfSorted . slice ( 0 , 30 ) ) {
178+ const pct = ( ( hits / sfTotal ) * 100 ) . toFixed ( 1 ) . padStart ( 5 ) ;
179+ console . log ( ` ${ fn . padEnd ( 58 ) } ${ String ( hits ) . padStart ( 7 ) } ${ pct } %` ) ;
180+ }
181+
182+ writeFileSync ( join ( __dirname , 'cpu-profile-stringify.cpuprofile' ) , JSON . stringify ( sfProfile ) ) ;
183+ console . log ( '\n Full profile saved to benchmark/cpu-profile-stringify.cpuprofile' ) ;
184+ sfSession . disconnect ( ) ;
185+
140186session . disconnect ( ) ;
141187console . log ( '\nDone.' ) ;
0 commit comments