I think demerphq mentioned it already, but index() returns 0 if the 0-th character matches. It returns -1 if nothing in the string matches ( unless someone has played with $[ ).
I also had a couple of other thoughts. Surely the Inline::C solutions are faster, but I'm still trying to wring performance out of pure Perl. 1. Why not use $s2 through the reference as well? and 2. What about use bytes (); and then explicitly using bytes::substr and bytes::index instead of doing the import?
This code tests both of those together, for a whopping improvement over my solutions using the import and just using $s1 by reference.
sub mrm_6 {
# from mrn_5, testing bytes::misc explicitly instead of importing
# also in-place using of $s2
my ( $s1, $s2 ) = @_;
use bytes ();
my $pos = 0;
while ( -1 < ( $pos = bytes::index( $$s1, '\0', $pos ) ) ) {
bytes::substr( $$s1, $pos, 1, bytes::substr( $$s2, $pos, 1 ) )
+;
}
}
The results are impressive for such simple changes:
Strawberry Perl 5.8.8 on WinXP, AthlonXP 2400+, 1Gig
Rate ikegami_s
ikegami_s 37.0/s --
avar 188/s 409%
avar2 192/s 418%
avar2_pos 282/s 663%
ikegami_tr 342/s 825%
moritz 783/s 2018%
avar2_pos_inplace 1640/s 4338%
mrm_3 2436/s 6491%
mrm_4 2449/s 6524%
mrm_5 2459/s 6553%
mrm_1 2517/s 6709%
mrm_6 3372/s 9023%
cygperl 5.8.6 on the same machine as above
Rate ikegami_s
ikegami_s 37.9/s --
avar 285/s 650%
avar2 310/s 718%
ikegami_tr 316/s 733%
avar2_pos 709/s 1769%
moritz 1002/s 2543%
mrm_5 3631/s 9474%
mrm_3 3841/s 10027%
mrm_4 3913/s 10219%
mrm_1 4044/s 10562%
avar2_pos_inplace 4393/s 11484%
mrm_6 6237/s 16345%
perl 5.8.7 on Mandriva Linux 2006 Athlon 1000, 512MB RAM
Rate ikegami_s
ikegami_s 17.2/s --
avar 168/s 876%
avar2 187/s 983%
ikegami_tr 205/s 1091%
avar2_pos 307/s 1684%
moritz 620/s 3499%
mrm_4 1088/s 6218%
avar2_pos_inplace 1184/s 6775%
mrm_3 1184/s 6775%
mrm_5 1224/s 7006%
mrm_1 1240/s 7101%
mrm_6 1921/s 11052%
... and perhaps a sign of good things to come:
perl 5.9.5 on the above-mentioned Linux box
Rate ikegami_s
ikegami_s 13.3/s --
avar 172/s 1189%
ikegami_tr 176/s 1220%
avar2 182/s 1267%
avar2_pos 258/s 1837%
moritz 412/s 2987%
avar2_pos_inplace 776/s 5722%
mrm_3 780/s 5749%
mrm_1 785/s 5788%
mrm_5 798/s 5882%
mrm_4 806/s 5942%
mrm_6 2683/s 20026%
ActivePerl 5.8.0 on the Windows box didn't fare so well under this one
I killed the benchmark for ActivePerl at 7 minutes CPU time, over 23 million page faults, and over 175MB of memory usage. I guess there's probably a bug in bytes or in perl in that build that's causing the thrashing.
|