can't do it with Inline::C, can I?
Yes I can, no need in separate source file; here to prove my claims from parent node:
use strict;
use warnings;
use feature 'say';
use Benchmark 'cmpthese';
use Config;
say "$^V / $Config{ archname } / $Config{ gccversion }";
my $L = 1e6;
my $str = '1' x $L;
BEGIN {
our $c = << 'END_OF_C';
int %s( SV* str ) {
STRLEN len;
char* buf = SvPVbyte( str, len );
len --;
int acc = 0;
int cum = 0;
int max = -1;
for( int i = 0; i < len; i ++ ) {
int one = buf[ i ] - '0';
acc += one;
cum += one ? -1 : 1;
if ( cum > max ) max = cum;
}
return acc + max + ( buf[ len ] == '1' );
}
END_OF_C
}
use Inline C => '
#pragma GCC target( "avx2" )
#pragma GCC optimize( "O3" )
' . sprintf our $c, 'mscore_optimised';
use Inline C => sprintf our $c, 'mscore_default';
my %tests = (
default => sub { mscore_default( $str )},
optimised => sub { mscore_optimised( $str )},
);
say 'uniform string:';
cmpthese -1, \%tests;
substr $str, rand $L, 1 , '0' for 1 .. $L;
say 'random string:';
cmpthese -1, \%tests;
__END__
v5.42.0 / MSWin32-x64-multi-thread / 13.2.0
uniform string:
Rate default optimised
default 897/s -- -19%
optimised 1111/s 24% --
random string:
Rate optimised default
optimised 245/s -- -73%
default 897/s 266% --