Skip to content

Instantly share code, notes, and snippets.

@cygx
Last active July 15, 2019 18:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cygx/9c94eefdf6300f726bc698655555d73b to your computer and use it in GitHub Desktop.
Save cygx/9c94eefdf6300f726bc698655555d73b to your computer and use it in GitHub Desktop.
Performance of Perl6 string operations
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;
}
};
month global match split on regex split on string index FORTRAN FORTRAN using NQP builtins
0 35.72 86.74 27.35 2.83 2.35 0.43
2 32.03 66.54 16.35 2.23 1.79 0.42
6 34.00 60.58 12.94 2.26 1.84 0.42
8 23.93 56.86 12.16 1.80 1.80 0.41
9 22.45 39.17 7.61 2.09 1.67 0.38
12 18.33 12.03 7.56 1.73 1.70 0.33
14 17.02 10.13 7.39 1.70 1.69 0.38
15 14.46 10.05 7.49 1.78 1.59 0.38
17 17.02 12.47 8.92 1.98 1.53 0.38
18 14.29 10.35 7.62 1.65 1.34 0.35
20 14.08 11.11 8.44 1.78 1.53 0.82
26 14.52 10.11 7.52 1.61 1.36 0.38
27 11.36 8.38 6.53 1.19 1.22 0.34
28 11.24 8.17 3.93 1.15 1.32 0.32
32 10.20 6.78 3.50 0.50 0.91 0.30
34 9.59 6.82 3.16 0.43 0.62 0.24
35 9.65 6.41 3.08 0.37 0.52 0.22
36 9.45 6.31 2.91 0.34 0.44 0.22
42 9.75 5.83 2.44 0.5 0.39 0.2
43 9.82 5.84 2.41 0.5 0.42 0.19
45 8.22 4.62 2.31 0.45 0.44 0.19
p5 0.15 0.20 0.21 0.18 0.12 n/a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment