Results for string: "aabcdabcabcecdecd " Rate blazar kramba ikegami lodin oha blazar 464/s -- -77% -89% -90% -90% kramba 2062/s 344% -- -52% -54% -58% ikegami 4255/s 817% 106% -- -4% -13% lodin 4444/s 858% 116% 4% -- -9% oha 4878/s 951% 137% 15% 10% -- Results for string: "aabcdabcabcecdecd aabcdabcabcecdecd " Rate blazar oha kramba ikegami lodin blazar 92.4/s -- -85% -86% -86% -87% oha 610/s 560% -- -7% -9% -14% kramba 658/s 612% 8% -- -1% -7% ikegami 667/s 621% 9% 1% -- -6% lodin 709/s 667% 16% 8% 6% -- Results for string: "aabcdabcabcecdecd aabcdabcabcecdecd aabcdabcabcecdecd aabcdabcabcecdecd " Rate blazar lodin ikegami oha kramba blazar 21.4/s -- -85% -86% -86% -90% lodin 144/s 574% -- -3% -5% -35% ikegami 148/s 594% 3% -- -2% -33% oha 151/s 607% 5% 2% -- -31% kramba 220/s 930% 53% 48% 46% -- #### #!/usr/bin/perl use strict; use warnings; use Data::Dumper; use constant MIN_LENGTH => 2; use constant MIN_REPEATS => 2; use Benchmark qw/:all :hireswallclock/; my $str='aabcdabcabcecdecd'; sub blazar { local $_=shift; my $l=length; my %count; for my $off (0..$l-1) { for my $len (MIN_LENGTH .. $l-$off) { my $s = substr $_, $off, $len; $count{ $s } ||= ()= /$s/g; } $count{$_} < MIN_REPEATS and delete $count{$_} for keys %count; } \%count; } sub oha { my $s=shift; my %saw; while($s =~ /(..+)(?=.*?\1)/g) { for my $x (0..length $1) { @saw{ map {substr $1, $x, $_} $x+2..length $1 } = (); } } $saw{$_} =()= $s =~ /\Q$_/g for keys %saw; \%saw; } sub ikegami { my $str = shift; local our %counts; $str =~ / (.{2,}) # or (.+) (?(?{ !$counts{$1} })(?=.*\1)) (?{ ++$counts{$1} }) (?!) /x; \%counts; } sub lodin { my $str = shift; local our %count; $str =~ / (.{2,}) (?(?{ $count{$1} }) (?!) ) .* \1 (?{ ($count{$1} ||= 1)++ }) (?!) /x; \%count; } { my %count; sub kramba { my( $string) = @_; my $length = length( $string ); if ($length < MIN_LENGTH) { for (keys %count) { delete $count{$_} if $count{$_} < MIN_REPEATS; } return \%count; } for my $l (MIN_LENGTH..$length) { my $s = substr( $string, 0, $l ); $count{ $s } += 1; } kramba( substr( $string, 1 ) ); }; } for my $multiplier (1, 2, 4) { my $work_str = "$str " x $multiplier; print "Results for string:\n\n\"$work_str\"\n\n"; cmpthese 2000/$multiplier => { blazar => sub { blazar $work_str }, oha => sub { oha $work_str }, kramba => sub { kramba $work_str }, ikegami => sub { ikegami $work_str }, lodin => sub { lodin $work_str }, } }