sub pwc {
my ( $from, $to, $target ) = @_;
use integer;
my @witnesses = ([ 4, 7 ], [ 2 .. 9 ]);
my ( %pairs, $j );
for ( my $i = ( $from + 2 ) / 3 * 3; $i <= $to; $i += 3 ) {
my $i_key = join '', sort split '', $i;
my $k = $i % 9 ? 0 : 1;
for ( @{ $witnesses[ $k ]}) {
last if length( $j = $i * $_ ) != length( $i );
$pairs{ $i }{ $j } = $_
unless $i_key ne join '', sort split '', $j
}
for ( @{ $witnesses[ $k ]}) {
last if length( $j = $i / $_ ) != length( $i );
$pairs{ $i }{ $j } = -$_
unless $i % $_
|| exists $pairs{ $j } &&
exists $pairs{ $j }{ $i }
|| $i_key ne join '', sort split '', $j
}
}
return scalar grep { %$_ >= $target } values %pairs
}
####
use Sort::Packed 'sort_packed';
sub pwc_p {
my ( $from, $to, $target ) = @_;
use integer;
my @witnesses = ([ 4, 7 ], [ 2 .. 9 ]);
my ( %pairs, $j );
for ( my $i = ( $from + 2 ) / 3 * 3; $i <= $to; $i += 3 ) {
sort_packed C => my $i_key = $i;
my $k = $i % 9 ? 0 : 1;
for ( @{ $witnesses[ $k ]}) {
last if length( $j = $i * $_ ) != length( $i );
sort_packed C => my $j_key = $j;
$pairs{ $i }{ $j } = $_
unless $i_key ne $j_key
}
for ( @{ $witnesses[ $k ]}) {
last if length( $j = $i / $_ ) != length( $i );
next if $i % $_;
sort_packed C => my $j_key = $j;
$pairs{ $i }{ $j } = -$_
unless exists $pairs{ $j } &&
exists $pairs{ $j }{ $i }
|| $i_key ne $j_key
}
}
return scalar grep { %$_ >= $target } values %pairs
}
####
sub ugly {
my ( $from, $to, $target ) = @_;
use integer;
my @witnesses = ([ 4, 7 ], [ 2 .. 9 ]);
my ( %pairs, $j );
for ( my $i = ( $from + 2 ) / 3 * 3; $i <= $to; $i += 3 ) {
my $k = $i % 9 ? 0 : 1;
for ( @{ $witnesses[ $k ]}) {
last if length( $j = $i * $_ ) != length( $i );
$pairs{ $i }{ $j } = $_
unless $i =~ tr/12// != $j =~ tr/12//
|| $i =~ tr/34// != $j =~ tr/34//
|| $i =~ tr/56// != $j =~ tr/56//
|| $i =~ tr/78// != $j =~ tr/78//
|| $i =~ tr/9// != $j =~ tr/9//
|| $i =~ tr/2// != $j =~ tr/2//
|| $i =~ tr/4// != $j =~ tr/4//
|| $i =~ tr/6// != $j =~ tr/6//
|| $i =~ tr/8// != $j =~ tr/8//
}
for ( @{ $witnesses[ $k ]}) {
last if length( $j = $i / $_ ) != length( $i );
$pairs{ $i }{ $j } = -$_
unless $i % $_
|| exists $pairs{ $j } &&
exists $pairs{ $j }{ $i }
|| $i =~ tr/12// != $j =~ tr/12//
|| $i =~ tr/34// != $j =~ tr/34//
|| $i =~ tr/56// != $j =~ tr/56//
|| $i =~ tr/78// != $j =~ tr/78//
|| $i =~ tr/9// != $j =~ tr/9//
|| $i =~ tr/2// != $j =~ tr/2//
|| $i =~ tr/4// != $j =~ tr/4//
|| $i =~ tr/6// != $j =~ tr/6//
|| $i =~ tr/8// != $j =~ tr/8//
}
}
return scalar grep { %$_ >= $target } values %pairs
}
####
say "$^V / $Config{ archname } / $Config{ gccversion }";
cmpthese -3, {
pwc => sub { pwc( 1500, 2500, 1 )},
pwc_p => sub { pwc_p( 1500, 2500, 1 )},
ugly => sub { ugly( 1500, 2500, 1 )},
};
# v5.32.1 / MSWin32-x64-multi-thread / 8.3.0
# Rate pwc pwc_p ugly
# pwc 737/s -- -48% -77%
# pwc_p 1424/s 93% -- -56%
# ugly 3251/s 341% 128% --
####
"2490" => { 4920 => 2, 9240 => 4 },
"3b10" => { "13b0" => -3, "b130" => 3 },
####
sub pwc_px {
my ( $from, $to, $target ) = @_;
use integer;
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
my @adjust = qw/ 0 2 1 0 1 0 0 2 1 0 0 1 0 2 1 /;
$from += $adjust[ $from % 15 ];
my @witnesses = ([ 6, 11 ], [ 4, 7, 10, 13 ], [ 2 .. 15 ]);
my ( %pairs, $jx );
for my $i ( $from .. $to ) {
next if $i % 3 and $i % 5;
my $k = $i % 15 ? $i % 5 ? 0 : 1 : 2;
my $ix = sprintf '%x', $i;
sort_packed C => my $i_key = $ix;
for ( @{ $witnesses[ $k ]}) {
$jx = sprintf '%x', $i * $_;
last if length( $jx ) != length( $ix );
sort_packed C => my $j_key = $jx;
$pairs{ $ix }{ $jx } = $_
unless $i_key ne $j_key
}
for ( @{ $witnesses[ $k ]}) {
$jx = sprintf '%x', $i / $_;
last if length( $jx ) != length( $ix );
next if $i % $_;
sort_packed C => my $j_key = $jx;
$pairs{ $ix }{ $jx } = -$_
unless exists $pairs{ $jx } &&
exists $pairs{ $jx }{ $ix }
|| $i_key ne $j_key
}
}
return scalar grep { %$_ >= $target } values %pairs
}
sub ugly_x {
my ( $from, $to, $target ) = @_;
use integer;
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
my @adjust = qw/ 0 2 1 0 1 0 0 2 1 0 0 1 0 2 1 /;
$from += $adjust[ $from % 15 ];
my @witnesses = ([ 6, 11 ], [ 4, 7, 10, 13 ], [ 2 .. 15 ]);
my ( %pairs, $jx );
for my $i ( $from .. $to ) {
next if $i % 3 and $i % 5;
my $k = $i % 15 ? $i % 5 ? 0 : 1 : 2;
my $ix = sprintf '%x', $i;
for ( @{ $witnesses[ $k ]}) {
$jx = sprintf '%x', $i * $_;
last if length( $jx ) != length( $ix );
$pairs{ $ix }{ $jx } = $_
unless $ix =~ tr/1// != $jx =~ tr/1//
|| $ix =~ tr/2// != $jx =~ tr/2//
|| $ix =~ tr/3// != $jx =~ tr/3//
|| $ix =~ tr/4// != $jx =~ tr/4//
|| $ix =~ tr/5// != $jx =~ tr/5//
|| $ix =~ tr/6// != $jx =~ tr/6//
|| $ix =~ tr/7// != $jx =~ tr/7//
|| $ix =~ tr/8// != $jx =~ tr/8//
|| $ix =~ tr/9// != $jx =~ tr/9//
|| $ix =~ tr/a// != $jx =~ tr/a//
|| $ix =~ tr/b// != $jx =~ tr/b//
|| $ix =~ tr/c// != $jx =~ tr/c//
|| $ix =~ tr/d// != $jx =~ tr/d//
|| $ix =~ tr/e// != $jx =~ tr/e//
|| $ix =~ tr/f// != $jx =~ tr/f//
}
for ( @{ $witnesses[ $k ]}) {
$jx = sprintf '%x', $i / $_;
last if length( $jx ) != length( $ix );
$pairs{ $ix }{ $jx } = -$_
unless $i % $_
|| exists $pairs{ $jx } &&
exists $pairs{ $jx }{ $ix }
|| $ix =~ tr/1// != $jx =~ tr/1//
|| $ix =~ tr/2// != $jx =~ tr/2//
|| $ix =~ tr/3// != $jx =~ tr/3//
|| $ix =~ tr/4// != $jx =~ tr/4//
|| $ix =~ tr/5// != $jx =~ tr/5//
|| $ix =~ tr/6// != $jx =~ tr/6//
|| $ix =~ tr/7// != $jx =~ tr/7//
|| $ix =~ tr/8// != $jx =~ tr/8//
|| $ix =~ tr/9// != $jx =~ tr/9//
|| $ix =~ tr/a// != $jx =~ tr/a//
|| $ix =~ tr/b// != $jx =~ tr/b//
|| $ix =~ tr/c// != $jx =~ tr/c//
|| $ix =~ tr/d// != $jx =~ tr/d//
|| $ix =~ tr/e// != $jx =~ tr/e//
|| $ix =~ tr/f// != $jx =~ tr/f//
}
}
return scalar grep { %$_ >= $target } values %pairs
}
cmpthese -3, {
pwc_px => sub { pwc_px( 0x1DEA, 0xC0DE, 2 )},
ugly_x => sub { ugly_x( 0x1DEA, 0xC0DE, 2 )},
};
# Rate pwc_px ugly_x
# pwc_px 23.1/s -- -38%
# ugly_x 37.2/s 61% --
####
@witnesses = ([ 8, 15, 22, 29 ], [ 6, 11, 16, 21, 26, 31 ], [ 2 .. 35 ]);
####
{
j376 => { "36j7" => -6 },
j736 => { "376j" => -6 },
k03c => { "3c0k" => -6 },
k12c => { "1c2k" => -15 },
k3c0 => { "3ck0" => -6 },
lm3o => { "3lom" => -6 },
m3lo => { "3olm" => -6 },
n174 => { "17n4" => -19 },
n840 => { "4n80" => -5 },
nbco => { bnoc => -2 },
o029 => { "2o09" => -9 },
o290 => { "2o90" => -9 },
o4dt => { "4tod" => -5 },
onbc => { cbno => -2 },
p046 => { "460p" => -6 },
p460 => { "46p0" => -6 },
pb6s => { "6bsp" => -4 },
}
***
Rate pwc_p36 ugly_36
pwc_p36 2.02/s -- -14%
ugly_36 2.36/s 17% --