1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
#!/usr/bin/env perl
use strict;
use warnings;
use Time::HiRes 'time';
use List::Util 'sum';
use IPC::System::Simple 'system';
use autodie;
use Parse::BACKPAN::Packages;
use LWP::Simple;
use Archive::Tar;
use Path::Tiny;
my $backpan = Parse::BACKPAN::Packages->new;
my @cmops = $backpan->distributions('Class-MOP');
my @mooses = $backpan->distributions('Moose');
my $cmop_version = 0;
my $cmop_dir;
my $base = "http://backpan.cpan.org/";
my %time;
my %mem;
open my $output, ">", "moose_bench.txt";
for my $moose (@mooses) {
my $moose_dir = build($moose);
# Find the CMOP dependency
my $makefile = path("$moose_dir/Makefile.PL")->slurp_utf8;
my ($cmop_dep) = $makefile =~ /Class::MOP.*?([0-9._]+)/
or die "Unable to find Class::MOP version dependency in $moose_dir/Makefile.PL";
# typo?
$cmop_dep = '0.64_07' if $cmop_dep eq '0.6407';
# nonexistent dev releases?
$cmop_dep = '0.79' if $cmop_dep eq '0.78_02';
$cmop_dep = '0.83' if $cmop_dep eq '0.82_01';
bump_cmop($cmop_dep, $moose);
warn "Building $moose_dir";
eval {
system("(cd '$moose_dir' && '$^X' '-I$cmop_dir/lib' Makefile.PL && make && sudo make install) >/dev/null");
my @times;
for (1 .. 5) {
my $start = time;
system(
$^X,
"-I$moose_dir/lib",
"-I$cmop_dir/lib",
'-e', 'package Class; use Moose;',
);
push @times, time - $start;
}
$time{$moose->version} = sum(@times) / @times;
$mem{$moose->version} = qx[$^X -I$moose_dir/lib -I$cmop_dir/lib -MGTop -e 'my (\$gtop, \$before); BEGIN { \$gtop = GTop->new; \$before = \$gtop->proc_mem(\$\$)->size; } package Class; use Moose; print \$gtop->proc_mem(\$\$)->size - \$before'];
my $line = sprintf "%7s: %0.4f (%s), %d bytes\n",
$moose->version,
$time{$moose->version},
join(', ', map { sprintf "%0.4f", $_ } @times),
$mem{$moose->version};
print $output $line;
};
warn $@ if $@;
}
require Chart::Clicker;
require Chart::Clicker::Data::Series;
require Chart::Clicker::Data::DataSet;
my @versions = sort keys %time;
my @startups = map { $time{$_} } @versions;
my @memories = map { int($mem{$_} / 1024) } @versions;
my @keys = (0..$#versions);
my $cc = Chart::Clicker->new(width => 900, height => 400);
my $sutime = Chart::Clicker::Data::Series->new(
values => \@startups,
keys => \@keys,
name => 'Startup Time',
);
my $def = $cc->get_context('default');
$def->domain_axis->tick_values(\@keys);
$def->domain_axis->tick_labels(\@versions);
$def->domain_axis->tick_label_angle(1.57);
$def->domain_axis->tick_font->size(8);
$def->range_axis->fudge_amount('0.05');
my $context = Chart::Clicker::Context->new(name => 'memory');
$context->range_axis->tick_values([qw(1024 2048 3072 4096 5120)]);
$context->range_axis->format('%d');
$context->domain_axis->hidden(1);
$context->range_axis->fudge_amount('0.05');
$cc->add_to_contexts($context);
my $musage = Chart::Clicker::Data::Series->new(
values => \@memories,
keys => \@keys,
name => 'Memory Usage (kb)'
);
my $ds1 = Chart::Clicker::Data::DataSet->new(series => [ $sutime ]);
my $ds2 = Chart::Clicker::Data::DataSet->new(series => [ $musage ]);
$ds2->context('memory');
$cc->add_to_datasets($ds1);
$cc->add_to_datasets($ds2);
$cc->write_output('moose_bench.png');
sub bump_cmop {
my $expected = shift;
my $moose = shift;
return $cmop_dir if $cmop_version eq $expected;
my @orig_cmops = @cmops;
shift @cmops until !@cmops || $cmops[0]->version eq $expected;
die "Ran out of cmops, wanted $expected for "
. $moose->distvname
. " (had " . join(', ', map { $_->version } @orig_cmops) . ")"
if !@cmops;
$cmop_version = $cmops[0]->version;
$cmop_dir = build($cmops[0]);
warn "Building $cmop_dir";
system("(cd '$cmop_dir' && '$^X' Makefile.PL && make && sudo make install) >/dev/null");
return $cmop_dir;
}
sub build {
my $dist = shift;
my $distvname = $dist->distvname;
return $distvname if -d $distvname;
warn "Downloading $distvname";
my $tarball = get($base . $dist->prefix);
open my $handle, '<', \$tarball;
my $tar = Archive::Tar->new;
$tar->read($handle);
$tar->extract;
my ($arbitrary_file) = $tar->list_files;
(my $directory = $arbitrary_file) =~ s{/.*}{};
return $directory;
}
|