Monday 16 July 2018

PHP Benchmark: Multiple str_replace() vs One str_replace() With Array

PHP Benchmark: Multiple str_replace() vs One str_replace() With Array

I’m a massive fan of optimisation. Inparticular I’m talking about optimising PHP code, rather than, say, HTML code which would improve a users experience. Sometimes however I think it can go too far when it comes to doing something that results in saving just a few milliseconds. In these scenarios, the time taken to perform and code the optimisation is often greater than the total time the optimisation will ultimately save in the long run.
There are times however that I do think optimisation is a worthwhile task:
  • When something (ie a script) is ran thousands, if not millions of times a day
  • When the optimisation will have a positive impact on a servers memory and performance
  • When a script is time sensitive and needs to complete as quickly as possible
In the scenario that led me to perform this benchmark test, it was the first option in the list above that got me initially thinking. One of my scripts contained about 500 individual calls to the PHP function str_replace(), and this script was called hundreds of thousands of times a day. One slight optimisation would have a big impact.
The Question
Which is quicker? Doing hundreds of individual calls to str_replace(), or doing just a few but using an array to store the search and replace values?
The Test
The test would be broken down into two parts. One where just a few replacements happen on a short string just a few words long, and one where lots of replacements would happen on a very long string over 25,000 characters. In both cases we will do lots of singular calls to str_replace() and then just one call to str_replace() but using arrays for the search and replace parameters. Each would be performed in a loop iterating 10,000 times.
To make it fairer the tests would be performed multiple times at the same time of the day on the same server.
A copy of the script used can be found below should you want to run the benchmark for yourself:
The Results
Short String, Few Replacements
The code for this first test was as follows:

  1. $string = "My cat is furry and likes to eat fish";  
  2.   
  3. ## Doing one str_replace() at a time on a short string  
  4.   
  5. $startTime = microtime(true);  
  6.   
  7. for ($i=0; $i<10000; $i++)  
  8. {  
  9.     $newString = $string;  
  10.     $newString = str_replace("cat""dog"$newString);  
  11.     $newString = str_replace("furry""skinny"$newString);  
  12.     $newString = str_replace("likes""hates"$newString);  
  13.     $newString = str_replace("fish""stones"$newString);  
  14. }  
  15.   
  16. $endTime = microtime(true);  
  17.   
  18. echo "Took ".($endTime - $startTime)." microseconds";  
  19.   
  20. ## Doing one str_replace() in total using arrays  
  21.   
  22. $search = array("cat""furry""likes""fish");  
  23. $replace = array("dog""skinny""hates""stones");  
  24.   
  25. $startTime = microtime(true);  
  26.   
  27. for ($i=0; $i<10000; $i++)  
  28. {  
  29.     $newString = $string;  
  30.     $newString = str_replace($search$replace$newString);  
  31. }  
  32.   
  33. $endTime = microtime(true);  
  34.   
  35. echo "\nTook ".($endTime - $startTime)." microseconds";  
And the results were as follows:
Multiple str_replace()
0.14730405807495 microseconds
0.033537149429321 microseconds
0.033782958984375 microseconds
0.033676147460938 microseconds
One str_replace()
0.026539087295532 microseconds
0.025756120681763 microseconds
0.026238918304443 microseconds
0.026527881622314 microseconds
Long String, Lots Of Replacements
The second test was similar to the first but contained a very long string with five times as many replacements. The code for this test was:

  1. $string = str_repeat("My cat is furry and likes to eat fish. He thinks that rabbits are rubbish and that his owner is brilliant. His name is Alfred and he is 24 years old in August. His hobbies include skiing, archery, swimming and rowing. He does get tired though after all of this exercise. ", 100);  
  2.   
  3. ## Doing one str_replace() at a time on a short string  
  4.   
  5. $startTime = microtime(true);  
  6.   
  7. for ($i=0; $i<10000; $i++)  
  8. {  
  9.     $newString = $string;  
  10.     $newString = str_replace("cat""dog"$newString);  
  11.     $newString = str_replace("furry""skinny"$newString);  
  12.     $newString = str_replace("likes""hates"$newString);  
  13.     $newString = str_replace("fish""stones"$newString);  
  14.     $newString = str_replace("thinks""knows"$newString);  
  15.     $newString = str_replace("rabbits""camels"$newString);  
  16.     $newString = str_replace("rubbish""excellent"$newString);  
  17.     $newString = str_replace("brilliant""exceptional"$newString);  
  18.     $newString = str_replace("His""Her"$newString);  
  19.     $newString = str_replace("Alfred""Alison"$newString);  
  20.     $newString = str_replace(" he "" she "$newString);  
  21.     $newString = str_replace("24""33"$newString);  
  22.     $newString = str_replace("August""October"$newString);  
  23.     $newString = str_replace("hobbies""interests"$newString);  
  24.     $newString = str_replace("skiing""trains"$newString);  
  25.     $newString = str_replace("archery""aeroplanes"$newString);  
  26.     $newString = str_replace("swimming""motorsport"$newString);  
  27.     $newString = str_replace("rowing""ships"$newString);  
  28.     $newString = str_replace("He ""She "$newString);  
  29.     $newString = str_replace("tired""excited"$newString);  
  30. }  
  31.   
  32. $endTime = microtime(true);  
  33.   
  34. echo "Took ".($endTime - $startTime)." microseconds";  
  35.   
  36. ## Doing one str_replace() in total using arrays  
  37.   
  38. $search = array("cat""furry""likes""fish""thinks""rabbits""rubbish""brilliant""His""Alfred"" he ""24""August""hobbies""skiing""archery""swimming""rowing""He ""tired");  
  39. $replace = array("dog""skinny""hates""stones""knows""camels""excellent""exceptional""Her""Alison"" she ""33""October""interests""trains""aeroplanes""motorsport""ships""She""excited");  
  40.   
  41. $startTime = microtime(true);  
  42.   
  43. for ($i=0; $i<10000; $i++)  
  44. {  
  45.     $newString = $string;  
  46.     $newString = str_replace($search$replace$newString);  
  47. }  
  48.   
  49. $endTime = microtime(true);  
  50.   
  51. echo "\nTook ".($endTime - $startTime)." microseconds";  
And the results:
Multiple str_replace()
19.818342924118 microseconds
19.381294965744 microseconds
19.562654972076 microseconds
19.654101848602 microseconds
One str_replace()
18.64848780632 microseconds
18.245759010315 microseconds
18.476965904236 microseconds
18.209582090378 microseconds
Conclusion
In both tests it seems apparent that doing a single call to str_replace() is better (or at least quicker) than doing lots of individual calls. The savings are quite small but do build up when we’re talking about this being something that’s done potentially millions of times a day.

0 comments:

Post a Comment