#!/usr/bin/perl -w # # curltime: gather time statistics from curl, to evaluate book speed # while factoring out rendering. # # 2007-09-26: Written by Steven J. DeRose, sderose@acm.org. use strict; use Getopt::Long; my $version = "2010-09-12"; my $quiet = 0; my $rep = 1; my $verbose = 0; # Process options # Getopt::Long::Configure ("ignore_case"); my $result = GetOptions( "h|help|?" => sub { system "perldoc curltime"; exit; }, "q|quiet!" => \$quiet, "rep|reps=n" => \$rep, "v|verbose+" => \$verbose, "version" => sub { die "Version of $version, by Steven J. DeRose.\n"; } ); ($result) || die "Bad options.\n"; ############################################################################### # my $uri = $ARGV[0]; # The -w option writes to stdout, so we redirect the file output with -o. # -s makes curl silent. my $curlOpts = ($quiet) ? "-s":""; $curlOpts .= " -o /dev/null -w '%{time_total} %{time_namelookup}" . " %{time_pretransfer} %{time_starttransfer} %{size_download}" . " %{speed_download}'"; my @stats = (); my $startTime = time(); print "\n"; for (my $i=1; $i<=$rep; $i++) { my $cmd = "curl $curlOpts $uri"; ($verbose) && print "Running: $cmd\n"; my $rc = `$cmd`; ($verbose) && print "Rep $i times: $rc\n"; push @stats, $rc; } my $endTime = time(); print "\n"; print "Total elapsed time: " . timeCode($endTime-$startTime) . "\n"; my ($_tot, $_lookup, $_pretr, $_starttr, $_size, $_speed) = 0; my $maxtime = 0.0; my $mintime = 1.0E20; for my $s (@stats) { my ($tot, $lookup, $pretr, $starttr, $size, $speed) = split(/\s+/, $s); if ($tot > $maxtime ) { $maxtime = $tot; } if ($tot < $mintime ) { $mintime = $tot; } $_tot += $tot; $_lookup += $lookup; $_pretr += $pretr; $_starttr += $starttr; $_size += $size; $_speed += $speed; } my $frep = $rep + 0.000; print "\nAverages over $rep repetitions:\n"; print pad(" Total time:",30) . fpad($_tot /$frep) . "\n"; print pad(" Lookup time:",30) . fpad($_lookup /$frep) . "\n"; print pad(" Pretransfer time:",30) . fpad($_pretr /$frep) . "\n"; print pad(" Starttransfer time:",30) . fpad($_starttr/$frep) . "\n"; print pad(" Size:",30) . fpad($_size /$frep) . "\n"; print pad(" Speed:",30) . fpad($_speed /$frep) . "\n"; # print join("\n",@stats) . "\n"; exit; ############################################################################### # sub getTimeData() { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime; $year+=1900; my @mons = split(/\s+/,"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"); my $monname = $mons[$mon]; $mon+=1; my @wdays = split(/\s+/, "Monday Tuesday Wednesday Thursday Friday Saturday"); my $dayname = $wdays[$mon]; ($mon<10) && ($mon = "0$mon"); ($mday<10) && ($mday = "0$mday"); ($hour<10) && ($hour = "0$hour"); ($min<10) && ($min = "0$min"); ($sec<10) && ($sec = "0$sec"); my $isotime = "$year-$mon-$mday\@$hour:$min:$sec"; return($isotime); } ############################################################################### # # timeCode: Change elapsed seconds into hh:mm:ss form. # Params: 0: Time as a number of seconds. # ############################################################################### sub timeCode { my $etime = $_[0]; my $s = $etime % 60; if ($s < 10) { $s = "0$s"; } my $m = int($etime/60) % 60; if ($m < 10) { $m = "0$m"; } my $h = int($etime/3660); return("$h:$m:$s"); } ############################################################################### # sub pad { my $s = $_[0]; my $len = $_[1]; if ($len <= 2) { $len = 8; } my $needed = $len - length($s); if ($needed > 0) { $s .= (" " x $needed); } return($s); } sub fpad { my $s = sprintf("%12.3f", $_[0]); return($s); } ############################################################################### # sub showUsage { warn " =head1 Usage curltime [options] [uri] Loads the specified URI and reports time taken. Does not support the full (and impressive) list of curl options. =head1 Options =over =item * B<-q> Suppress most messages, and pass '-s' to curl to turn off its progress reports. =item * B<-reps n> Repeat curling the file n times. =item * B<-v> Add more detailed messages. =item * B<-version> Display version info and exit. =head1 Notes on times reported (see 'man curl') time_total Total time that the full operation lasted. time_namelookup From the start until the name resolving was completed. time_connect From the start until the connect was completed. time_pretransfer From the start until the file transfer is about to begin. All pre-transfer commands and negotiations. time_starttransfer From start until the first byte is about to be transfered. pretransfer + time for server to calculate the result. size_download Total bytes downloaded. speed_download Average speed curl measured for the complete download. =head1 Ownership This work by Steven J. DeRose is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License. For further information on this license, see http://creativecommons.org/licenses/by-sa/3.0/. The author's present email is sderose at acm.org. For the most recent version, see http://www.derose.net/steve/utilities/. =cut "; }