use Inline C => <<'END_OF_C'; int histcmp( SV* sv1, SV* sv2 ) { // return 1; STRLEN len; char* s1 = SvPVbyte( sv1, len ); char* s2 = SvPVbyte( sv2, len ); char h1[ 10 ]; char h2[ 10 ]; memset( h1, 0, sizeof( h1 )); memset( h2, 0, sizeof( h2 )); for ( int i = 0; i < len; i ++ ) { h1[ s1[ i ] - '0' ] ++; h2[ s2[ i ] - '0' ] ++; } return memcmp( h1, h2, 10 ); } END_OF_C sub pwc_c { 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 histcmp( $i, $j ) } for ( @{ $witnesses[ $k ]}) { last if length( $j = $i / $_ ) != length( $i ); $pairs{ $i }{ $j } = -$_ unless $i % $_ || exists $pairs{ $j } && exists $pairs{ $j }{ $i } || histcmp( $i, $j ) } } return scalar grep { %$_ >= $target } values %pairs } cmpthese -3, { pwc_c => sub { pwc_c( 1500, 2500, 1 )}, ugly => sub { ugly( 1500, 2500, 1 )}, }; cmpthese -3, { pwc_c => sub { pwc_c( 13_427_000, 14_100_000, 2 )}, ugly => sub { ugly( 13_427_000, 14_100_000, 2 )}, }; # Rate pwc_c ugly # pwc_c 2865/s -- -12% # ugly 3251/s 13% -- # Rate pwc_c ugly # pwc_c 3.42/s -- -9% # ugly 3.75/s 10% --