use strict; use warnings; use Benchmark qw(:all); use Text::LevenshteinXS qw(distance); sub compare_rg0now { return 0 unless length $_[0] == length $_[1]; return 1 if $_[0] eq $_[1]; my $diff = 0; my @l1 = split //, $_[0]; my @l2 = split //, $_[1]; for(my $i = 0; $i < scalar @l1; $i++){ $diff++ if $l1[$i] ne $l2[$i]; return 0 if $diff > 1; } return 1; } sub compare_blazar { (my $xor=$_[0]^$_[1]) =~ tr/\0//d; length $xor < 2; } sub compare_BrowserUk { return ( length $_[0] == length $_[1] ) && ( length( $_[0] ) - 1 <= ( $_[0] ^ $_[1] ) =~ tr[\0][\0] ) } sub compare_ikegami { return unless length $_[0] == length $_[1]; # Omit if expecting differences almost all the time. return 1 if $_[0] eq $_[1]; my $limit = 1; foreach (split('', $_[0]^$_[1])) { next unless ord; return 0 unless $limit--; } return 1; } sub compare_levenshtein { return ( length $_[0] == length $_[1] ) && ( distance($_[0], $_[1]) < 2); } my @data = ( [ qw( abab abab ) ], [ qw( abab abaa ) ], [ qw( abab qrst ) ], [ qw( abab abba ) ], [ qw( abab ababa ) ], ); cmpthese(-3, { 'rg0now' => sub {for(@data) {compare_rg0now(@$_)} }, 'blazar' => sub {for(@data) {compare_blazar(@$_)} }, 'BrowserUk' => sub {for(@data) {compare_BrowserUk(@$_)} }, 'ikegami' => sub {for(@data) {compare_ikegami(@$_)} }, 'levenshtein' => sub {for(@data) {compare_levenshtein(@$_)} }, });