Skip to content

Instantly share code, notes, and snippets.

@cygx
Last active October 14, 2015 17:25
Show Gist options
  • Save cygx/cbb08f0c01a0cc28c9d3 to your computer and use it in GitHub Desktop.
Save cygx/cbb08f0c01a0cc28c9d3 to your computer and use it in GitHub Desktop.
P5 vs P6 shootout
my $N := 100_000;
my %words := hash();
print("generating input...");
my @lines := [];
my $i := 1;
while $i <= $N {
@lines.push("$i\t42\n");
++$i;
}
my $input := join('', @lines);
print("done.\n");
my $start := nqp::time_n();
my str $str := $input;
my int $pos := 0;
my int $chars := nqp::chars($str);
while $pos < $chars {
my int $tab := nqp::index($str, "\t", $pos);
my int $nl := nqp::index($str, "\n", $tab);
%words{nqp::substr($str, $pos, $tab - $pos)} :=
nqp::substr($str, $tab + 1, $nl - $tab - 1);
$pos := $nl + 1;
}
my $end := nqp::time_n();
say(nqp::sprintf("%u words parsed in %.2fs (%s)",
[+%words, $end - $start, 'FORTRAN']));
use v6;
my $N = 100_000;
my %words;
print "generating input...";
my $input = join '', map { "$_\t42\n" }, 1..$N;
print "done.\n";
sub bench($name, &code) {
%words = ();
my $start = now;
code;
my $end = now;
say "{ +%words } words parsed in { ($end - $start).round(0.01) }s ($name)";
}
bench 'global match', {
%words = ($input ~~ m:g/(<-[\n\t]>+)\t(\N+)/).map(*>>.Str.Slip);
}
bench 'split on regex', {
for $input.lines {
my ($k, $v) = .split(/\t/, 2);
%words{$k} = $v;
}
}
bench 'split on string', {
for $input.lines {
my ($k, $v) = .split("\t", 2);
%words{$k} = $v;
}
}
bench 'index', {
for $input.lines {
my $tab = .index("\t");
%words{.substr(0, $tab)} = .substr($tab + 1);
}
}
bench 'FORTRAN', {
my str $str = $input;
my int $pos = 0;
my int $chars = $str.chars;
while $pos < $chars {
my int $tab = $str.index("\t", $pos);
my int $nl = $str.index("\n", $tab);
%words{$str.substr($pos, $tab - $pos)} =
$str.substr($tab + 1, $nl - $tab - 1);
$pos = $nl + 1;
}
}
bench 'FORTRAN using NQP builtins', {
use nqp;
my str $str = $input;
my int $pos = 0;
my int $chars = nqp::chars($str);
while $pos < $chars {
my int $tab = nqp::index($str, "\t", $pos);
my int $nl = nqp::index($str, "\n", $tab);
%words{nqp::p6box_s(nqp::substr($str, $pos, $tab - $pos))} =
nqp::p6box_s(nqp::substr($str, $tab + 1, $nl - $tab - 1));
$pos = $nl + 1;
}
}
use v5;
use Time::HiRes qw(time);
use File::Slurp qw(read_file);
my $N = 100_000;
my %words;
print "generating input...";
my $input = join '', map { "$_\t42\n" } 1..$N;
print "done.\n";
sub bench {
my ($name, $code) = @_;
%words = ();
my $start = time;
$code->();
my $end = time;
printf "%u words parsed in %.2fs (%s)\n",
scalar keys(%words), $end - $start, $name;
}
bench 'global match', sub {
%words = ($input =~ /([^\n\t]+)\t(\N+)/g);
};
bench 'split on regex', sub {
for ($input =~ /\N+/g) {
my ($k, $v) = split(/\t/, $_, 2);
$words{$k} = $v;
}
};
bench 'split on string', sub {
for ($input =~ /\N+/g) {
my ($k, $v) = split("\t", $_, 2);
$words{$k} = $v;
}
};
bench 'index', sub {
for ($input =~ /\N+/g) {
my $tab = index($_, "\t");
$words{substr($_, 0, $tab)} = substr($_, $tab + 1);
}
};
bench 'FORTRAN', sub {
my $str = $input;
my $pos = 0;
my $chars = length($str);
while ($pos < $chars) {
my $tab = index($str, "\t", $pos);
my $nl = index($str, "\n", $tab);
$words{substr($str, $pos, $tab - $pos)} =
substr($str, $tab + 1, $nl - $tab - 1);
$pos = $nl + 1;
}
};
$ perl bench.pl
generating input...done.
100000 words parsed in 0.14s (global match)
100000 words parsed in 0.18s (split on regex)
100000 words parsed in 0.20s (split on string)
100000 words parsed in 0.18s (index)
100000 words parsed in 0.12s (FORTRAN)
$ perl6 bench.p6
generating input...done.
100000 words parsed in 35.72s (global match)
100000 words parsed in 86.74s (split on regex)
100000 words parsed in 27.35s (split on string)
100000 words parsed in 2.83s (index)
100000 words parsed in 2.35s (FORTRAN)
100000 words parsed in 0.43s (FORTRAN using NQP builtins)
$ nqp bench.nqp
generating input...done.
100000 words parsed in 0.18s (FORTRAN)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment