Commit | Line | Data |
---|---|---|
21c4e167 H |
1 | #!/usr/bin/env perl |
2 | use strict; | |
3 | use warnings; | |
4 | ||
5 | package Time::Bench; | |
6 | ||
7 | use Time::HiRes; | |
8 | ||
9 | our ($sr, $su, $ss) = (0,0,0); #calibrators | |
10 | ||
11 | sub new { #constructor | |
12 | my ($self, $ncalib) = @_; | |
13 | $ncalib || $self->bench_calibrate(); | |
14 | return $self; | |
15 | } | |
16 | ||
17 | sub bench { | |
18 | shift; | |
19 | my $r0 = [Time::HiRes::gettimeofday()]; | |
20 | my ($u0, $s0, $cu0, $cs0) = times; | |
21 | qx{ @_ >/dev/null }; | |
22 | my ($u, $s, $cu, $cs) = times; | |
23 | my $r = Time::HiRes::tv_interval($r0); | |
24 | #real, user, system | |
25 | return($r-$sr, $cu-$cu0-($u-$u0)-$su, $cs-$cs0-($s-$s0)-$ss); | |
26 | #return($r, $cu-$cu0-($u-$u0), $cs-$cs0-($s-$s0)); | |
27 | #return($r-$sr, $cu-$cu0-$su, $cs-$cs0-$su); | |
28 | #return($r, $cu-$cu0, $cs-$cs0); | |
29 | } | |
30 | ||
31 | sub bench_multiple { | |
32 | my ($this, $cmd, $times) = @_; | |
33 | my ($ar, $au, $as) = (0,0,0); | |
34 | print "\n==> Measuring: $cmd\n"; | |
35 | for(my $i=1;$i<=$times;$i++) { | |
36 | print " => run\t$i\t/$times\r"; | |
37 | my ($r, $u, $s) = $this->bench($cmd); | |
38 | $ar += $r; | |
39 | $au += $u; | |
40 | $as += $s; | |
41 | } | |
42 | print "\n => DONE!\n"; | |
43 | return ($ar/$times, $au/$times, $as/$times); | |
44 | } | |
45 | ||
46 | sub bench_print { | |
47 | shift; | |
48 | my ($r, $u, $s) = @_; | |
49 | print "real\t $r\n", | |
50 | "user\t $u\n", | |
51 | "sys\t $s\n"; | |
52 | ||
53 | } | |
54 | ||
55 | sub bench_calibrate { | |
56 | my ($this) = @_; | |
57 | print "==> Calibrating..."; | |
58 | ($sr, $su, $ss) = (0,0,0); | |
59 | ($sr, $su, $ss) = $this->bench_multiple('true', 1000); | |
60 | print " => Correction:\n"; | |
61 | $this->bench_print($sr, $su, $ss); | |
62 | return ($sr, $su, $ss); | |
63 | } | |
64 | ||
65 | sub bench_sort { | |
66 | my ($this, %hash) = @_; | |
67 | my $i = 1; | |
68 | foreach my $key (sort {$hash{$a} <=> $hash{$b} } keys %hash) { | |
69 | print "$i.)\t$hash{$key}\t\t:\t$key\n"; | |
70 | $i++; | |
71 | } | |
72 | } | |
73 | ||
74 | sub bench_compare { | |
75 | my ($this, $times, @cmds) = @_; | |
76 | my (%r, %u, %s); | |
77 | foreach(@cmds) { | |
78 | ($r{$_}, $u{$_}, $s{$_}) = $this->bench_multiple($_, $times); | |
79 | $this->bench_print($r{$_}, $u{$_}, $s{$_}); | |
80 | } | |
81 | return (\%r, \%u, \%s); | |
82 | } | |
83 | ||
84 | sub bench_results { | |
85 | my ($this, $r, $u, $s) = @_; | |
86 | print "\n==> SORTED RESULTS!\n"; | |
87 | print " => by Real time:\n"; | |
88 | $this->bench_sort(%$r); | |
89 | print " => by User time:\n"; | |
90 | $this->bench_sort(%$u); | |
91 | print " => by System time:\n"; | |
92 | $this->bench_sort(%$s); | |
93 | } | |
94 | ||
95 | package main; | |
96 | ||
97 | if($#ARGV < 0) { | |
98 | print "$0 (CopyLefted by Harvie 2o1o)\n", | |
99 | "\t- Compares execution times of given commands\n", | |
100 | "\t- (You can compare multiple alghorithms to find the fastest one.)\n", | |
101 | "\t- Usage:\t$0 <passes> <cmd1> [<cmd2> <cmd3> ...]\n", | |
102 | "\t\t- passes: how many times i should measure (special calibration is done for values < 0)\n", | |
103 | "\t\t- cmd1,cmd2,...: commands to compare\n", | |
104 | "\n", | |
105 | "\t- Example:\t$0 10 'sleep 1' 'sleep 2'\n", | |
106 | "\t- Example:\t$0 100 'ls' 'ls -l'\n", | |
107 | "\t- Example:\t$0 100 'ping google.com -c 1' 'ping yahoo.com -c 1'\n", | |
108 | "\t- Example:\t$0 -1000 true false\n", | |
109 | "\n"; | |
110 | exit; | |
111 | } | |
112 | ||
113 | my $times = shift @ARGV; | |
114 | my $t = Time::Bench->new($times >= 0); #new(1) to disable calibration | |
115 | my ($r, $u, $s) = $t->bench_compare(abs($times), @ARGV); | |
116 | $t->bench_results($r, $u, $s); | |
117 |