Updates from Bernhard Fischer rep dot nop gmail com
[rrdtool.git] / examples / perftest.pl.in
1 #! @PERL@
2 #
3 # $Id:$
4 #
5 # Created By Tobi Oetiker <tobi@oetiker.ch>
6 # Date 2006-10-27
7 #
8 #makes programm work AFTER install
9
10 use lib qw( @prefix@/lib/perl );
11
12 print <<NOTE;
13
14 RRDtool Performance Tester
15 --------------------------
16 Runnion on $RRDs::VERSION;
17
18 RRDtool update performance is ultimately disk-bound. Since very little data
19 does actually get written to disk in a single update, the performance
20 is highly dependent on the cache situation in your machine.
21
22 This test tries to cater for this. It works like this:
23
24 1) Create 20k RRD files (and sync them to disk)
25
26 2) Update the RRD files several times in a row.
27    We run the Update several times to see the difference
28    it makes in the cache.
29
30 NOTE
31
32 use strict;
33 use Time::HiRes qw(time);
34 use RRDs;
35 use IO::File;
36 use Time::HiRes qw( usleep );
37
38 sub create($$){
39   my $file = shift;
40   my $time = shift;
41   my $start = time; #since we loaded HiRes
42   RRDs::create  ( $file.".rrd", "-b$time", qw(
43                         -s300                        
44                         DS:in:GAUGE:400:U:U
45                         DS:out:GAUGE:400:U:U
46                         RRA:AVERAGE:0.5:1:600
47                         RRA:AVERAGE:0.5:6:600
48                         RRA:MAX:0.5:6:600
49                         RRA:AVERAGE:0.5:24:600
50                         RRA:MAX:0.5:24:600
51                         RRA:AVERAGE:0.5:144:600
52                         RRA:MAX:0.5:144:600
53                 ));
54    my $total = time - $start;
55    my $error =  RRDs::error;
56    die $error if $error;
57    return $total;
58 }
59
60 sub update($$){
61   my $file = shift;
62   my $time = shift;
63   my $in = rand(1000);
64   my $out = rand(1000);
65   my $start = time;
66   my $ret = RRDs::updatev($file.".rrd", $time.":$in:$out");
67 #  print join("",map {"  $_ " . $ret->{$_}."\n" } grep /AVERAGE.\[1\]/, sort keys %$ret)."\n** $time\n\n";
68   # sync updates to disk immediately  
69 #  usleep(1) if (rand(3) <1 );
70   my $total = time - $start;
71   my $error =  RRDs::error;
72   die $error if $error;
73   return $total;
74 }
75
76 sub tune($){
77   my $file = shift;
78   my $start = time;
79   RRDs::tune ($file.".rrd", "-a","in:U","-a","out:U","-d","in:GAUGE","-d","out:GAUGE");
80   my $total = time - $start;
81   my $error =  RRDs::error;
82   die $error if $error;
83   return $total;
84 }
85
86 sub infofetch($){
87   my $file = shift;
88   my $start = time;
89   my $info = RRDs::info ($file.".rrd");
90   my $error =  RRDs::error;
91   die $error if $error;
92   my $lasttime =  $info->{last_update} - $info->{last_update} % $info->{step};           
93   my $fetch = RRDs::fetch ($file.".rrd",'AVERAGE','-s',$lasttime-1,'-e',$lasttime);
94   my $total = time - $start;
95   my $error =  RRDs::error;
96   die $error if $error;
97   return $total;
98 }
99
100 sub stddev ($$$){ #http://en.wikipedia.org/wiki/Standard_deviation
101   my $sum = shift;
102   my $squaresum = shift;
103   my $count = shift;
104   return sqrt( 1 / $count * ( $squaresum - $sum*$sum / $count ))
105 }
106
107 sub makerrds($$$$){
108     my $count = shift;
109     my $total = shift;
110     my $list = shift;
111     my $time = shift;
112     my @files;
113     for (1..$count){
114         my $id = sprintf ("%07d",$total);
115         $id =~ s/^(.)(.)(.)(.)(.)//;
116         push @$list, "$1/$2/$3/$4/$5/$id";    
117         -d "$1" or mkdir "$1";
118         -d "$1/$2" or mkdir "$1/$2";
119         -d "$1/$2/$3" or mkdir "$1/$2/$3";
120         -d "$1/$2/$3/$4" or mkdir "$1/$2/$3/$4";
121         -d "$1/$2/$3/$4/$5" or mkdir "$1/$2/$3/$4/$5";
122         push @files, $list->[$total];
123         create $list->[$total++],$time-2;
124         print STDERR ".";
125     }
126    for (@files){ 
127         my $fd = new IO::File("$_.rrd","r");
128         if (defined $fd) {
129             $fd->sync;
130             $fd->close;
131         } else {
132             warn "failed to sync $_\n";
133         }        
134     }
135     return $count;
136 }
137     
138     
139 sub main (){
140     mkdir "db-$$" or die $!;
141     chdir "db-$$";
142
143     my $step = 100000; # number of rrds to creat for every round
144     
145     my @path;
146     my $time=int(time);
147
148     my $tracksize = 0;
149     my $uppntr = 0;
150
151     
152     my %squaresum = ( cr => 0, up => 0 );
153     my %sum = ( cr => 0, up => 0 );
154     my %count =( cr => 0, up => 0 );
155
156     my $printtime = time;
157     while (1) {
158         # enhance the track
159             $time += 300;
160         $tracksize += makerrds $step,$tracksize,\@path,$time;            
161         # run benchmark
162         for (0..10){
163             $time += 300;
164             my $count = 0;
165             my $sum = 0;
166             my $squaresum = 0;
167             for (my $i = 0; $i<$tracksize;$i ++){
168                my $elapsed = update($path[$i],$time); 
169                $sum += $elapsed;
170                $squaresum += $elapsed**2;
171                $count++;
172             };
173 #            for (my $i = 0; $i<$tracksize;$i ++){
174 #              my $fh = new IO::File "$path[$i].rrd","r";
175 #              if (defined $fh) {
176 #                  $fh->sync;
177 #                  $fh->close;
178 #                } else {
179 #                  warn "failed to sync $path[$i]\n";
180 #               }       
181 #            }
182             my $ups = $count/$sum;
183             my $sdv = stddev($sum,$squaresum,$count);
184             printf STDERR "%4d %6.0f Up/s (%6.5f sdv)\n",$count,$ups,$sdv;
185         }
186         print STDERR "\n";
187         exit ;
188     }
189 }
190
191 main;
192 use strict;
193 use Time::HiRes qw(time);
194 use RRDs;
195 use IO::File;
196 use Time::HiRes qw( usleep );
197
198 sub create($$){
199   my $file = shift;
200   my $time = shift;
201   my $start = time; #since we loaded HiRes
202   RRDs::create  ( $file.".rrd", "-b$time", qw(
203                         -s300                        
204                         DS:in:GAUGE:400:U:U
205                         DS:out:GAUGE:400:U:U
206                         RRA:AVERAGE:0.5:1:600
207                         RRA:AVERAGE:0.5:6:600
208                         RRA:MAX:0.5:6:600
209                         RRA:AVERAGE:0.5:24:600
210                         RRA:MAX:0.5:24:600
211                         RRA:AVERAGE:0.5:144:600
212                         RRA:MAX:0.5:144:600
213                 ));
214    my $total = time - $start;
215    my $error =  RRDs::error;
216    die $error if $error;
217    return $total;
218 }
219
220 sub update($$){
221   my $file = shift;
222   my $time = shift;
223   my $in = rand(1000);
224   my $out = rand(1000);
225   my $start = time;
226   my $ret = RRDs::updatev($file.".rrd", $time.":$in:$out");
227 #  print join("",map {"  $_ " . $ret->{$_}."\n" } grep /AVERAGE.\[1\]/, sort keys %$ret)."\n** $time\n\n";
228   # sync updates to disk immediately  
229 #  usleep(1) if (rand(3) <1 );
230   my $total = time - $start;
231   my $error =  RRDs::error;
232   die $error if $error;
233   return $total;
234 }
235
236 sub tune($){
237   my $file = shift;
238   my $start = time;
239   RRDs::tune ($file.".rrd", "-a","in:U","-a","out:U","-d","in:GAUGE","-d","out:GAUGE");
240   my $total = time - $start;
241   my $error =  RRDs::error;
242   die $error if $error;
243   return $total;
244 }
245
246 sub infofetch($){
247   my $file = shift;
248   my $start = time;
249   my $info = RRDs::info ($file.".rrd");
250   my $error =  RRDs::error;
251   die $error if $error;
252   my $lasttime =  $info->{last_update} - $info->{last_update} % $info->{step};           
253   my $fetch = RRDs::fetch ($file.".rrd",'AVERAGE','-s',$lasttime-1,'-e',$lasttime);
254   my $total = time - $start;
255   my $error =  RRDs::error;
256   die $error if $error;
257   return $total;
258 }
259
260 sub stddev ($$$){ #http://en.wikipedia.org/wiki/Standard_deviation
261   my $sum = shift;
262   my $squaresum = shift;
263   my $count = shift;
264   return sqrt( 1 / $count * ( $squaresum - $sum*$sum / $count ))
265 }
266
267 sub makerrds($$$$){
268     my $count = shift;
269     my $total = shift;
270     my $list = shift;
271     my $time = shift;
272     my @files;
273     for (1..$count){
274         my $id = sprintf ("%07d",$total);
275         $id =~ s/^(.)(.)(.)(.)(.)//;
276         push @$list, "$1/$2/$3/$4/$5/$id";    
277         -d "$1" or mkdir "$1";
278         -d "$1/$2" or mkdir "$1/$2";
279         -d "$1/$2/$3" or mkdir "$1/$2/$3";
280         -d "$1/$2/$3/$4" or mkdir "$1/$2/$3/$4";
281         -d "$1/$2/$3/$4/$5" or mkdir "$1/$2/$3/$4/$5";
282         push @files, $list->[$total];
283         create $list->[$total++],$time-2;
284         print STDERR ".";
285     }
286    for (@files){ 
287         my $fd = new IO::File("$_.rrd","r");
288         if (defined $fd) {
289             $fd->sync;
290             $fd->close;
291         } else {
292             warn "failed to sync $_\n";
293         }        
294     }
295     return $count;
296 }
297     
298     
299 sub main (){
300     mkdir "db-$$" or die $!;
301     chdir "db-$$";
302
303     my $step = 200000; # number of rrds to creat for every round
304     
305     my @path;
306     my $time=int(time);
307
308     my $tracksize = 0;
309     my $uppntr = 0;
310
311     
312     my %squaresum = ( cr => 0, up => 0 );
313     my %sum = ( cr => 0, up => 0 );
314     my %count =( cr => 0, up => 0 );
315
316     my $printtime = time;
317     while (1) {
318         # enhance the track
319             $time += 300;
320         $tracksize += makerrds $step,$tracksize,\@path,$time;            
321         # run benchmark
322         for (0..10){
323             $time += 300;
324             my $count = 0;
325             my $sum = 0;
326             my $squaresum = 0;
327             for (my $i = 0; $i<$tracksize;$i ++){
328                my $elapsed = update($path[$i],$time); 
329                $sum += $elapsed;
330                $squaresum += $elapsed**2;
331                $count++;
332             };
333 #            for (my $i = 0; $i<$tracksize;$i ++){
334 #              my $fh = new IO::File "$path[$i].rrd","r";
335 #              if (defined $fh) {
336 #                  $fh->sync;
337 #                  $fh->close;
338 #                } else {
339 #                  warn "failed to sync $path[$i]\n";
340 #               }       
341 #            }
342             my $ups = $count/$sum;
343             my $sdv = stddev($sum,$squaresum,$count);
344             printf STDERR "%4d %6.0f Up/s (%6.5f sdv)\n",$count,$ups,$sdv;
345         }
346         print STDERR "\n";
347         exit ;
348     }
349 }
350
351 main;