Benchmark in Perl – replace

if you want to check whats the fastest way to replace a string in Perl you could use the Benchmark-Module.I compared 4 different ways  :

#!/usr/bin/perl
use strict;
use warnings;
use Benchmark qw(:all) ;
use Inline 'C';


my $teststring;

#check result :
$teststring = "teststring1"; $teststring =~ s/1/2/g; 				print $teststring.$/;
$teststring = "teststring1"; $teststring =~ s/1/2/go; 				print $teststring.$/;
$teststring = "teststring1"; $teststring =~ tr/1/2/; 				print $teststring.$/;
$teststring = "teststring1"; $teststring = replace($teststring,"1","2"); 	print $teststring.$/;
$teststring = "teststring1"; $teststring = repl_str($teststring,"1","2"); 	print $teststring.$/;

#test one
 cmpthese(-4, {
'regex_normal' 		=> sub {$teststring = "teststring1"; $teststring =~ s/1/2/g; },
'regex_optimised' 	=> sub {$teststring = "teststring1"; $teststring =~ s/1/2/go; },
'translate' 		=> sub {$teststring = "teststring1"; $teststring =~ tr/1/2/; },
'perl_sub' 		=> sub {$teststring = "teststring1"; $teststring = replace($teststring,"1","2"); },
'C_replace_string' 	=> sub {$teststring = "teststring1"; $teststring = repl_str($teststring,"1","2"); },
});


#test two
 cmpthese(-4, {
'regex_normal' 		=> sub {$teststring = "teststring1stringxstring"; $teststring =~ s/string/test/g; },
'regex_optimised' 	=> sub {$teststring = "teststring1stringxstring"; $teststring =~ s/string/test/go; },
'translate' 		=> sub {$teststring = "teststring1stringxstring"; $teststring =~ tr/string/test/; },
'perl_sub' 		=> sub {$teststring = "teststring1stringxstring"; $teststring = replace($teststring,"string","test"); },
'C_replace_string' 	=> sub {$teststring = "teststring1stringxstring"; $teststring = repl_str($teststring,"string","test"); },
});


sub replace {
my $string  = shift;
my $old     = shift;
my $new     = shift;
my $pos     = index($string, $old);
while ( $pos > -1 ) {
 substr( $string, $pos, length( $old ), $new );
 $pos = index( $string, $old, $pos + length( $new ));
}
return($string);
}

__END__
__C__
char* repl_str(const char *str, const char *old, const char *new){
	char *ret, *r;
	const char *p, *q;
	size_t oldlen = strlen(old);
	size_t count, retlen, newlen = strlen(new);

	if (oldlen != newlen) {
		for (count = 0, p = str; (q = strstr(p, old)) != NULL; p = q + oldlen)
			count++;
		retlen = p - str + strlen(p) + count * (newlen - oldlen);
	} else
		retlen = strlen(str);

	if ((ret = malloc(retlen + 1)) == NULL)
		return NULL;

	for (r = ret, p = str; (q = strstr(p, old)) != NULL; p = q + oldlen) {
		ptrdiff_t l = q - p;
		memcpy(r, p, l);
		r += l;
		memcpy(r, new, newlen);
		r += newlen;
	}
	strcpy(r, p);

	return ret;
}

the result looks like:

teststring2
teststring2
teststring2
teststring2
teststring2
                      Rate perl_sub C_replace_string regex_normal regex_optimised translate
perl_sub          632214/s       --             -68%         -68%            -70%      -91%
C_replace_string 1961177/s     210%               --          -2%             -8%      -71%
regex_normal     1999403/s     216%               2%           --             -7%      -71%
regex_optimised  2142180/s     239%               9%           7%              --      -69%
translate        6843359/s     982%             249%         242%            219%        --
                      Rate perl_sub regex_normal regex_optimised C_replace_string translate
perl_sub          430150/s       --         -50%            -50%             -57%      -92%
regex_normal      861549/s     100%           --             -0%             -14%      -85%
regex_optimised   862213/s     100%           0%              --             -14%      -85%
C_replace_string  998062/s     132%          16%             16%               --      -82%
translate        5603343/s    1203%         550%            550%             461%        --

Always check you sub results (Line 1-5) and make more test cases,

at the first case (Line 6) we see that for single character the best solution is to use regex.If you want to replace a longer string better use a C function.But in both cases its better to use the /o flag for regex to optimize, but then you cant interpolate a string in to the regex.And if you only want to replaxe use tr its the fastest.

4 thoughts on “Benchmark in Perl – replace”

  1. I’m really enjoying the design and layout of your blog. It’s a very
    easy on the eyes which makes it much more enjoyable for me to come here and visit more often. Did you hire out a developer to
    create your theme? Fantastic work!

  2. I got this website from my pal who shared with me regarding
    this web page and now this time I am browsing
    this web site and reading very informative articles at this place.

  3. Someone necessarily lend a hand to make seriously articles I would
    state. That is the very first time I frequented your web page and
    thus far? I surprised with the research you made to make this particular publish
    incredible. Fantastic process!

  4. I have been exploring for a little bit for any high-quality articles or weblog posts in this sort of area .
    Exploring in Yahoo I at last stumbled upon this site. Studying
    this information So i’m satisfied to show that I have an incredibly just right uncanny feeling I came upon exactly what I needed.
    I such a lot undoubtedly will make sure to don?t disregard this site and give it a look
    regularly.

Leave a Reply to google api console Cancel reply

Your email address will not be published.

5 × two =