split is slow. However, if you want just the first character of the string (I often do), then you can significantly speed up split by giving it the value 2 as LIMIT argument.
Benchmarked code from above (obviously on a faster machine) with 1 million iterations:
split: 17 wallclock secs (16.69 usr + 0.02 sys = 16.71 CPU) @ 59
+844.40/s (n=1000000)
substr: 0 wallclock secs ( 0.74 usr + 0.00 sys = 0.74 CPU) @ 13
+51351.35/s (n=1000000)
unpack: 1 wallclock secs ( 1.02 usr + 0.00 sys = 1.02 CPU) @ 98
+0392.16/s (n=1000000)
Benchmarking a very similar code, but instead looking for the 1st char only and giving split a ,2 limit:
split: 2 wallclock secs ( 1.16 usr + 0.00 sys = 1.16 CPU) @ 86
+2068.97/s (n=1000000)
substr: 1 wallclock secs ( 0.70 usr + 0.00 sys = 0.70 CPU) @ 14
+28571.43/s (n=1000000)
unpack: 0 wallclock secs ( 0.96 usr + 0.00 sys = 0.96 CPU) @ 10
+41666.67/s (n=1000000)
#!/usr/bin/perl -w
use strict;
use Benchmark;
use vars qw/$str/;
$str = "123456789asgdjlaskjglkajblnlbnlaqjteoijqotijwojgl;akjglkj";
timethese(shift || 1000000, {
'unpack' => sub { my $char = getn_unpack($str, 1) },
'substr' => sub { my $char = getn_substr($str, 1) },
'split' => sub { my $char = getn_split($str, 1) }
});
sub getn_unpack {
return unpack "x" . ($_[1]-1) . "a", $_[0];
}
sub getn_substr {
return substr $_[0], $_[1]-1, 1;
}
sub getn_split {
return +(split //, $_[0],2)[$_[1]-1];
}
Still slower than the other solutions, but nevertheless a speedup of over 10 to an unrestricted split. See if using the LIMIT argument in split would help your code.