stats.cc (1670B)
1 #include <stdio.h> 2 #include <math.h> 3 #include <algorithm> 4 5 #include "intrinsics.h" 6 #include "stats.h" 7 #include "ggformat.h" 8 #include "rng/pcg.h" 9 10 void stats_init( Stats * stats ) { 11 *stats = { }; 12 stats->rng = new_pcg(); 13 } 14 15 double stats_mean( const Stats * stats ) { 16 return stats->sum / stats->num_records; 17 } 18 19 double stats_stddev( const Stats * stats ) { 20 double variance = ( stats->sum_of_squares - ( stats->sum * stats->sum / stats->num_records ) ); 21 return sqrt( variance ); 22 } 23 24 void stats_record( Stats * stats, double x ) { 25 stats->sum += x; 26 stats->sum_of_squares += x * x; 27 28 // update min/max 29 if( stats->num_records == 0 ) { 30 stats->min = stats->max = x; 31 } 32 else { 33 stats->min = min( x, stats->min ); 34 stats->max = max( x, stats->max ); 35 } 36 37 // see if we should keep this sample 38 if( stats->num_records < STATS_NUM_QUART_SAMPLES ) { 39 stats->samples[ stats->num_records ] = x; 40 } 41 else { 42 double p = ( double ) STATS_NUM_QUART_SAMPLES / ( stats->num_records + 1.0 ); 43 44 if( rng_p( &stats->rng, p ) ) { 45 u32 i = rng_mod( &stats->rng, STATS_NUM_QUART_SAMPLES ); 46 stats->samples[ i ] = x; 47 } 48 } 49 50 stats->num_records++; 51 } 52 53 void format( FormatBuffer * fb, const Stats & stats, const FormatOpts & opts ) { 54 u32 num_samples = checked_cast< u32 >( min( stats.num_records, u64( STATS_NUM_QUART_SAMPLES ) ) ); 55 std::sort( stats.samples, stats.samples + num_samples ); 56 57 ggformat_impl( fb, "total = {}, n = {}, mean = {}, stddev = {}, min = {}, 25% = {}, 75% = {}, max = {}", 58 stats.sum, stats.num_records, 59 stats_mean( &stats ), stats_stddev( &stats ), 60 stats.min, 61 stats.samples[ num_samples / 4 ], 62 stats.samples[ num_samples * 3 / 4 ], 63 stats.max 64 ); 65 }