An Inline::C implementation runs about three times faster than the string interpolation version for integer comparison, and about 2.5 times faster for string comparisons.
use v5.16;
use strict;
use warnings;
use Inline 'C';
sub arrays_same_pp {
"@{$_[0]}" eq "@{$_[1]}";
}
our @x = map { int(rand() * 1_000_000) } 1..10;
our @y = @x;
use Benchmark 'cmpthese';
cmpthese -1, {
PP => '::arrays_same_pp(\@::x, \@::y)',
XS => '::arrays_same_i(\@::x, \@::y)',
};
__END__
__C__
int arrays_same_i (SV* x, SV* y) {
AV* arrx = (AV*)SvRV(x);
AV* arry = (AV*)SvRV(y);
if (arrx == arry) {
return 2;
}
int len = av_len(arrx);
if (len != av_len(arry)) {
return 0;
}
int i;
for (i=0; i<=len; i++) {
SV** elemx = av_fetch(arrx, i, 0);
SV** elemy = av_fetch(arry, i, 0);
int ix = SvIV(*elemx);
int iy = SvIV(*elemy);
if (ix != iy) {
return 0;
}
}
return 1;
}
int arrays_same_s (SV* x, SV* y) {
AV* arrx = (AV*)SvRV(x);
AV* arry = (AV*)SvRV(y);
if (arrx == arry) {
return 2;
}
int len = av_len(arrx);
if (len != av_len(arry)) {
return 0;
}
int i;
for (i=0; i<=len; i++) {
SV** elemx = av_fetch(arrx, i, 0);
SV** elemy = av_fetch(arry, i, 0);
STRLEN dummy;
char* strx = SvPV(*elemx, dummy);
char* stry = SvPV(*elemy, dummy);
if (strcmp(strx, stry) != 0) {
return 0;
}
}
return 1;
}
I might clean this up and release to CPAN if there's nothing similar already there.
|