new better ? performance test ... work in progress
[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 100 RRD files (and sync them to disk)
25
26 2) Update the 100 RRD file three times in a row.
27    We run the Update several times to see the difference
28    it makes in the cache.
29
30 3) Go back to 1)
31
32 NOTE
33
34 use strict;
35 use Time::HiRes qw(time);
36 use RRDs;
37 use IO::File;
38 use Time::HiRes qw( usleep );
39
40 sub create($$){
41   my $file = shift;
42   my $time = shift;
43   my $start = time; #since we loaded HiRes
44   RRDs::create  ( $file.".rrd", "-b$time", qw(
45                         -s300                        
46                         DS:in:GAUGE:400:U:U
47                         DS:out:GAUGE:400:U:U
48                         RRA:AVERAGE:0.5:1:600
49                         RRA:AVERAGE:0.5:6:600
50                         RRA:MAX:0.5:6:600
51                         RRA:AVERAGE:0.5:24:600
52                         RRA:MAX:0.5:24:600
53                         RRA:AVERAGE:0.5:144:600
54                         RRA:MAX:0.5:144:600
55                 ));
56    my $total = time - $start;
57    my $error =  RRDs::error;
58    die $error if $error;
59    return $total;
60 }
61
62 sub update($$){
63   my $file = shift;
64   my $time = shift;
65   my $in = rand(1000);
66   my $out = rand(1000);
67   my $start = time;
68   my $ret = RRDs::updatev($file.".rrd", $time.":$in:$out");
69 #  print join("",map {"  $_ " . $ret->{$_}."\n" } grep /AVERAGE.\[1\]/, sort keys %$ret)."\n** $time\n\n";
70   # sync updates to disk immediately  
71 #  usleep(1) if (rand(3) <1 );
72   my $total = time - $start;
73   my $error =  RRDs::error;
74   die $error if $error;
75   return $total;
76 }
77
78 sub tune($){
79   my $file = shift;
80   my $start = time;
81   RRDs::tune ($file.".rrd", "-a","in:U","-a","out:U","-d","in:GAUGE","-d","out:GAUGE");
82   my $total = time - $start;
83   my $error =  RRDs::error;
84   die $error if $error;
85   return $total;
86 }
87
88 sub infofetch($){
89   my $file = shift;
90   my $start = time;
91   my $info = RRDs::info ($file.".rrd");
92   my $error =  RRDs::error;
93   die $error if $error;
94   my $lasttime =  $info->{last_update} - $info->{last_update} % $info->{step};           
95   my $fetch = RRDs::fetch ($file.".rrd",'AVERAGE','-s',$lasttime-1,'-e',$lasttime);
96   my $total = time - $start;
97   my $error =  RRDs::error;
98   die $error if $error;
99   return $total;
100 }
101
102 sub stddev ($$$){ #http://en.wikipedia.org/wiki/Standard_deviation
103   my $sum = shift;
104   my $squaresum = shift;
105   my $count = shift;
106   return sqrt( 1 / $count * ( $squaresum - $sum*$sum / $count ))
107 }
108
109 sub makerrds($$$$){
110     my $count = shift;
111     my $total = shift;
112     my $list = shift;
113     my $time = shift;
114     my @files;
115     for (1..$count){
116         my $id = sprintf ("%07d",$total);
117         $id =~ s/^(.)(.)(.)(.)(.)//;
118         push @$list, "$1/$2/$3/$4/$5/$id";    
119         -d "$1" or mkdir "$1";
120         -d "$1/$2" or mkdir "$1/$2";
121         -d "$1/$2/$3" or mkdir "$1/$2/$3";
122         -d "$1/$2/$3/$4" or mkdir "$1/$2/$3/$4";
123         -d "$1/$2/$3/$4/$5" or mkdir "$1/$2/$3/$4/$5";
124         push @files, $list->[$total];
125         create $list->[$total++],$time-2;
126         print STDERR ".";
127     }
128    for (@files){ 
129         my $fd = new IO::File("$_.rrd","r");
130         if (defined $fd) {
131             $fd->sync;
132             $fd->close;
133         } else {
134             warn "failed to sync $_\n";
135         }        
136     }
137     return $count;
138 }
139     
140     
141 sub main (){
142     mkdir "db-$$" or die $!;
143     chdir "db-$$";
144
145     my $step = 100000; # number of rrds to creat for every round
146     
147     my @path;
148     my $time=int(time);
149
150     my $tracksize = 0;
151     my $uppntr = 0;
152
153     
154     my %squaresum = ( cr => 0, up => 0 );
155     my %sum = ( cr => 0, up => 0 );
156     my %count =( cr => 0, up => 0 );
157
158     my $printtime = time;
159     while (1) {
160         # enhance the track
161             $time += 300;
162         $tracksize += makerrds $step,$tracksize,\@path,$time;            
163         # run benchmark
164         for (0..10){
165             $time += 300;
166             my $count = 0;
167             my $sum = 0;
168             my $squaresum = 0;
169             for (my $i = 0; $i<$tracksize;$i ++){
170                my $elapsed = update($path[$i],$time); 
171                $sum += $elapsed;
172                $squaresum += $elapsed**2;
173                $count++;
174             };
175 #            for (my $i = 0; $i<$tracksize;$i ++){
176 #              my $fh = new IO::File "$path[$i].rrd","r";
177 #              if (defined $fh) {
178 #                  $fh->sync;
179 #                  $fh->close;
180 #                } else {
181 #                  warn "failed to sync $path[$i]\n";
182 #               }       
183 #            }
184             my $ups = $count/$sum;
185             my $sdv = stddev($sum,$squaresum,$count);
186             printf STDERR "%4d %6.0f Up/s (%6.5f sdv)\n",$count,$ups,$sdv;
187         }
188         print STDERR "\n";
189         exit ;
190     }
191 }
192
193 main;