I am not sure, if this works as you expect... maybe the
macros and wrappers generate a copy under the hood?
use Inline C;
use strict;
use warnings;
my $x = "012\xf0ABC\x0f\x00\x01\xff";
print unpack("H*", $x ), "\n"; # 303132f04142430f0001ff
flipbits( $x, length $x );
print unpack("H*", $x ), "\n"; # cfcecd0fbebdbcf0fffe00
__END__
__C__
void flipbits(char* a, int len ) {
for ( ; len-- ; ++a ) *a ^= 0xff;
}
Update: Switching to 32bit blocks gave a huge improvement on my 32bit setup...
void flipbits32(char* a, int len ) {
int blocks = len >> 2;
if ( sizeof blocks == 4 ) { /* try 32bit blocks */
for ( ; blocks-- ; a += 4 ) *( (unsigned int*) a ) ^= 0xffffffffU
+;
/* TODO: add treatment for last 1..3 bytes if len is not a multipl
+e of 4 */
} else { /* fallback to 8bit */
for ( ; len-- ; ++a ) *a ^= 0xff;
}
}
Benchmark:
Rate str inline inline32
str 69.1/s -- -37% -69%
flipbits 110/s 59% -- -51%
flipbits32 223/s 222% 103% --
Potential next steps which are also less general, but that's the price to pay: