use Benchmark qw( cmpthese ); use Inline CPP => 'DATA'; $main::string = '1234!' x 55e3; sub cpp { my $copy = $main::string; my $ix = nth_index( $copy, '!', 50000 ); substr( $copy, 0, $ix ) =~ tr/!/\n/; return \$copy; } sub regex { my $copy = $main::string; $myregexp::count = 0; $copy =~ s/!(??{ ( $myregexp::count++ < 50000 ) ? '' : '(?!)' })/\n/g; return \$copy; } sub buk { my( $p, $c ) = ( 0, 50e3 ); my $copy = $main::string; 1 while --$c and $p = index $copy, '!', $p; substr( $copy, 0, $p ) =~ tr[!][\n]; return \$copy; } cmpthese ( -5, { cpp => \&cpp, regex => \®ex, buk => \&buk, } ); __DATA__ __CPP__ #include long nth_index ( const char* c_str_haystack, const char* c_str_needle, long n, long offset = 0 ) { std::string haystack( c_str_haystack ); std::string needle( c_str_needle ); if( ! needle.size() || ! haystack.size() ) return -1; if( offset < 0 ) offset = 0; if( offset >= haystack.size() ) offset = haystack.size() - 1; size_t pos = haystack.find( needle, offset ); while( --n ) { pos = haystack.find( needle, pos + 1 ); if( pos == std::string::npos ) return -1; } return pos; }