@@ -12,12 +12,12 @@ use crate::options::{
1212 CmdFailureAction , CommandOutputPolicy , ExecutorKind , Options , OutputStyleOption ,
1313} ;
1414use crate :: outlier_detection:: { modified_zscores, OUTLIER_THRESHOLD } ;
15- use crate :: output:: format:: { format_duration, format_duration_unit} ;
15+ use crate :: output:: format:: { format_duration, format_duration_unit, BytesFormat } ;
1616use crate :: output:: progress_bar:: get_progress_bar;
1717use crate :: output:: warnings:: { OutlierWarningOptions , Warnings } ;
1818use crate :: parameter:: ParameterNameAndValue ;
1919use crate :: util:: exit_code:: extract_exit_code;
20- use crate :: util:: min_max:: { max, min} ;
20+ use crate :: util:: min_max:: { max, min, statistics } ;
2121use crate :: util:: units:: Second ;
2222use benchmark_result:: BenchmarkResult ;
2323use timing_result:: TimingResult ;
@@ -154,6 +154,12 @@ impl<'a> Benchmark<'a> {
154154 let mut memory_usage_byte: Vec < u64 > = vec ! [ ] ;
155155 let mut exit_codes: Vec < Option < i32 > > = vec ! [ ] ;
156156 let mut all_succeeded = true ;
157+ let mut voluntary_context_switches = Vec :: new ( ) ;
158+ let mut context_switches = Vec :: new ( ) ;
159+ let mut filesystem_input = Vec :: new ( ) ;
160+ let mut filesystem_output = Vec :: new ( ) ;
161+ let mut minor_page_faults = Vec :: new ( ) ;
162+ let mut major_page_faults = Vec :: new ( ) ;
157163
158164 let output_policy = & self . options . command_output_policies [ self . number ] ;
159165
@@ -282,6 +288,14 @@ impl<'a> Benchmark<'a> {
282288 times_system. push ( res. time_system ) ;
283289 memory_usage_byte. push ( res. memory_usage_byte ) ;
284290 exit_codes. push ( extract_exit_code ( status) ) ;
291+ if self . options . resource_usage {
292+ voluntary_context_switches. push ( res. voluntary_context_switches ) ;
293+ context_switches. push ( res. context_switches ) ;
294+ filesystem_input. push ( res. filesystem_input ) ;
295+ filesystem_output. push ( res. filesystem_output ) ;
296+ minor_page_faults. push ( res. minor_page_faults ) ;
297+ major_page_faults. push ( res. major_page_faults ) ;
298+ }
285299
286300 all_succeeded = all_succeeded && success;
287301
@@ -319,6 +333,14 @@ impl<'a> Benchmark<'a> {
319333 times_system. push ( res. time_system ) ;
320334 memory_usage_byte. push ( res. memory_usage_byte ) ;
321335 exit_codes. push ( extract_exit_code ( status) ) ;
336+ if self . options . resource_usage {
337+ voluntary_context_switches. push ( res. voluntary_context_switches ) ;
338+ context_switches. push ( res. context_switches ) ;
339+ filesystem_input. push ( res. filesystem_input ) ;
340+ filesystem_output. push ( res. filesystem_output ) ;
341+ minor_page_faults. push ( res. minor_page_faults ) ;
342+ major_page_faults. push ( res. major_page_faults ) ;
343+ }
322344
323345 all_succeeded = all_succeeded && success;
324346
@@ -389,6 +411,56 @@ impl<'a> Benchmark<'a> {
389411 num_str. dimmed( )
390412 ) ;
391413 }
414+
415+ if self . options . resource_usage {
416+ println ! ( ) ;
417+
418+ macro_rules! print_bytes_stats {
419+ ( $stats: expr, $title: literal) => { {
420+ let stats = statistics( & $stats) ;
421+ println!(
422+ " {:<7} ({} … {}|{} … {}): {:>8} … {:>8}{}{:<8} … {:>8}" ,
423+ $title,
424+ "min" . cyan( ) ,
425+ "mean" . green( ) . bold( ) ,
426+ "med" . blue( ) . bold( ) ,
427+ "max" . purple( ) ,
428+ format!( "{}" , BytesFormat ( stats. min) ) . cyan( ) ,
429+ format!( "{}" , BytesFormat ( stats. mean) ) . green( ) . bold( ) ,
430+ "|" . dimmed( ) ,
431+ format!( "{}" , BytesFormat ( stats. median) ) . blue( ) . bold( ) ,
432+ format!( "{}" , BytesFormat ( stats. max) ) . purple( )
433+ ) ;
434+ } } ;
435+ }
436+
437+ macro_rules! print_stats {
438+ ( $stats: expr, $title: literal) => { {
439+ let stats = statistics( & $stats) ;
440+ println!(
441+ " {:<7} ({} … {}|{} … {}): {:>8} … {:>8}{}{:<8} … {:>8}" ,
442+ $title,
443+ "min" . cyan( ) ,
444+ "mean" . green( ) . bold( ) ,
445+ "med" . blue( ) . bold( ) ,
446+ "max" . purple( ) ,
447+ format!( "{}" , stats. min) . cyan( ) ,
448+ format!( "{}" , stats. mean) . green( ) . bold( ) ,
449+ "|" . dimmed( ) ,
450+ format!( "{}" , stats. median) . blue( ) . bold( ) ,
451+ format!( "{}" , stats. max) . purple( )
452+ ) ;
453+ } } ;
454+ }
455+
456+ print_bytes_stats ! ( memory_usage_byte, "maxrss" ) ;
457+ print_stats ! ( voluntary_context_switches, "nvcsw" ) ;
458+ print_stats ! ( context_switches, "nivcsw" ) ;
459+ print_stats ! ( filesystem_input, "inblock" ) ;
460+ print_stats ! ( filesystem_output, "oublock" ) ;
461+ print_stats ! ( minor_page_faults, "minflt" ) ;
462+ print_stats ! ( major_page_faults, "majflt" ) ;
463+ }
392464 }
393465
394466 // Warnings
@@ -430,15 +502,15 @@ impl<'a> Benchmark<'a> {
430502 }
431503
432504 if !warnings. is_empty ( ) {
433- eprintln ! ( " " ) ;
505+ eprintln ! ( ) ;
434506
435507 for warning in & warnings {
436508 eprintln ! ( " {}: {}" , "Warning" . yellow( ) , warning) ;
437509 }
438510 }
439511
440512 if self . options . output_style != OutputStyleOption :: Disabled {
441- println ! ( " " ) ;
513+ println ! ( ) ;
442514 }
443515
444516 self . run_cleanup_command ( self . command . get_parameters ( ) . iter ( ) . cloned ( ) , output_policy) ?;
0 commit comments