1- use core:: cell:: { Cell , UnsafeCell } ;
2- use criterion:: { black_box, criterion_group, criterion_main, BatchSize , Criterion } ;
1+ use core:: cell:: UnsafeCell ;
2+ use core:: time:: Duration ;
3+ use criterion:: { black_box, criterion_group, criterion_main, Criterion } ;
4+ use std:: time:: Instant ;
35
46// Compile the production tracker without linking the PHP extension executable.
57#[ allow( dead_code) ]
@@ -10,6 +12,7 @@ use live_heap::{LiveHeapTracker, LocalLiveHeapTracker};
1012const BASE_ADDRESS : usize = 0x1000_0000 ;
1113const TRACKED_ALLOCATIONS : usize = 2048 ;
1214const ADDRESS_STRIDE : usize = 64 ;
15+ const BATCH_SIZE : u64 = 256 ;
1316
1417fn address ( index : usize ) -> usize {
1518 BASE_ADDRESS + index % TRACKED_ALLOCATIONS * ADDRESS_STRIDE
@@ -33,7 +36,7 @@ impl Tracker {
3336 }
3437
3538 fn track ( & self , ptr : usize , sample : [ usize ; 4 ] ) -> bool {
36- // Criterion invokes setup and measured routines sequentially.
39+ // SAFETY: Criterion invokes setup and measured routines sequentially.
3740 unsafe { ( & mut * self . local . get ( ) ) . track ( & self . shared , ptr, sample) }
3841 }
3942
@@ -51,60 +54,94 @@ fn populated_tracker() -> Tracker {
5154 tracker
5255}
5356
57+ fn measure_batched (
58+ iterations : u64 ,
59+ mut setup : impl FnMut ( usize ) ,
60+ mut routine : impl FnMut ( usize ) ,
61+ mut cleanup : impl FnMut ( usize ) ,
62+ ) -> Duration {
63+ let mut elapsed = Duration :: ZERO ;
64+ let mut completed = 0 ;
65+
66+ while completed < iterations {
67+ let count = BATCH_SIZE . min ( iterations - completed) ;
68+ for offset in 0 ..count {
69+ setup ( ( completed + offset) as usize ) ;
70+ }
71+
72+ let start = Instant :: now ( ) ;
73+ for offset in 0 ..count {
74+ routine ( ( completed + offset) as usize ) ;
75+ }
76+ elapsed += start. elapsed ( ) ;
77+
78+ for offset in 0 ..count {
79+ cleanup ( ( completed + offset) as usize ) ;
80+ }
81+ completed += count;
82+ }
83+
84+ elapsed
85+ }
86+
5487fn benchmark ( c : & mut Criterion ) {
5588 let mut group = c. benchmark_group ( "heap_live_tracking" ) ;
5689
5790 {
5891 let tracker = populated_tracker ( ) ;
59- let next = Cell :: new ( 0 ) ;
6092 group. bench_function ( "allocate_tracked" , |b| {
61- b. iter_batched (
62- || {
63- let index = next. get ( ) ;
64- next. set ( index + 1 ) ;
65- let ptr = untracked_address ( index) ;
66- let _ = tracker. untrack ( ptr) ;
67- ( ptr, [ 0 ; 4 ] )
68- } ,
69- |( ptr, sample) | black_box ( tracker. track ( ptr, sample) ) ,
70- BatchSize :: PerIteration ,
71- )
93+ b. iter_custom ( |iterations| {
94+ measure_batched (
95+ iterations,
96+ |index| {
97+ let _ = tracker. untrack ( untracked_address ( index) ) ;
98+ } ,
99+ |index| {
100+ black_box ( tracker. track ( untracked_address ( index) , [ 0 ; 4 ] ) ) ;
101+ } ,
102+ |index| {
103+ let _ = tracker. untrack ( untracked_address ( index) ) ;
104+ } ,
105+ )
106+ } )
72107 } ) ;
73108 }
74109
75110 {
76111 let tracker = populated_tracker ( ) ;
77- let next = Cell :: new ( 0 ) ;
78112 group. bench_function ( "free_tracked" , |b| {
79- b. iter_batched (
80- || {
81- let index = next. get ( ) ;
82- next. set ( index + 1 ) ;
83- let ptr = untracked_address ( index) ;
84- assert ! ( tracker. track( ptr, [ 0 ; 4 ] ) ) ;
85- ptr
86- } ,
87- |ptr| black_box ( tracker. untrack ( ptr) ) ,
88- BatchSize :: PerIteration ,
89- )
113+ b. iter_custom ( |iterations| {
114+ measure_batched (
115+ iterations,
116+ |index| {
117+ assert ! ( tracker. track( untracked_address( index) , [ 0 ; 4 ] ) ) ;
118+ } ,
119+ |index| {
120+ black_box ( tracker. untrack ( untracked_address ( index) ) ) ;
121+ } ,
122+ |index| {
123+ let _ = tracker. untrack ( untracked_address ( index) ) ;
124+ } ,
125+ )
126+ } )
90127 } ) ;
91128 }
92129
93130 {
94131 let tracker = populated_tracker ( ) ;
95- let next = Cell :: new ( 0 ) ;
96132 group. bench_function ( "free_untracked" , |b| {
97- b. iter_batched (
98- || {
99- let index = next. get ( ) ;
100- next. set ( index + 1 ) ;
101- let ptr = untracked_address ( index) ;
102- let _ = tracker. untrack ( ptr) ;
103- ptr
104- } ,
105- |ptr| black_box ( tracker. untrack ( ptr) ) ,
106- BatchSize :: PerIteration ,
107- )
133+ b. iter_custom ( |iterations| {
134+ measure_batched (
135+ iterations,
136+ |index| {
137+ let _ = tracker. untrack ( untracked_address ( index) ) ;
138+ } ,
139+ |index| {
140+ black_box ( tracker. untrack ( untracked_address ( index) ) ) ;
141+ } ,
142+ |_| { } ,
143+ )
144+ } )
108145 } ) ;
109146 }
110147
0 commit comments