On Sat, May 4, 2013 at 9:46 PM, Anthony Ferrara <ircmax...@gmail.com> wrote:
> Laruence, > > > foreach ($replacements as $regex => $callback) { > > > $str = preg_replace_callback($regex, $callback, $str); > > > } > > > > > > > So if there are 10 regex in the array, you will got 10 DO_FCALL. 10 > times > > arguments accept, 10 times etc... > > > > and AS I already said: IT is inefficient. I personally can not accept > it. > > > > thanks > > > > > My initial reaction was that the difference in runtime is going to be so > insignificant that it's the very definition of a micro-optimization between > the two. And unless you're doing it millions of times in a hot-loop, it's > never even going to be realized. I was going to reply to that effect. > > Then I decided to write a quick test. > > $count = 100; > > $start = microtime(true); > for ($i = 0; $i < $count; $i++) { > $str = "abc"; > $str = preg_replace_callback('/a/', function($a) { return > strtoupper($a[0]); }, $str); > $str = preg_replace_callback('/b/', function($a) { return > strtoupper($a[0]); }, $str); > $str = preg_replace_callback('/c/', function($a) { return > strtoupper($a[0]); }, $str); > $str = preg_replace_callback('/a/', function($a) { return > strtolower($a[0]); }, $str); > $str = preg_replace_callback('/b/', function($a) { return > strtolower($a[0]); }, $str); > $str = preg_replace_callback('/c/', function($a) { return > strtolower($a[0]); }, $str); > } > echo "Completed in " . (microtime(true) - $start) . " Seconds\n"; > > $start = microtime(true); > for ($i = 0; $i < $count; $i++) { > $str = "abc"; > $str = preg_replace(array( > '/a/e', > '/b/e', > '/c/e', > '/a/e', > '/b/e', > '/c/e', > ), > array( > 'strtoupper(\'$1\')', > 'strtoupper(\'$1\')', > 'strtoupper(\'$1\')', > 'strtolower(\'$1\')', > 'strtolower(\'$1\')', > 'strtolower(\'$1\')', > ), > $str > ); > } > echo "Completed in " . (microtime(true) - $start) . " Seconds\n"; > > So basically, it's comparing the old behavior (one call to preg_replace) > that you want to emulate, with what Nikita is suggesting. > > I ran it on 3v4l (http://3v4l.org/dRjtU) and the results were quite > surprising. I was expecting the first to be slightly slower than the > second. But the reality surprised me: > > Completed in 0.00076389312744141 Seconds Completed in 0.0012428760528564 > Seconds > > As it turns out, calling preg_replace_callback() multiple times is almost > 50% faster than using a single call to preg_replace(). > > It's likely due to the precompiled nature of closures, vs the compilation > happening multiple times at invocation in the preg_replace /e case. > > But it's still worth noting that switching from the /e style to a more > traditional preg_replace_callback implementation will get you a significant > boost in performance of that. > > Now, keep in mind, we're talking 0.000005 seconds saved per "execution" > (group of 6 replacements). So it's not likely to matter much or be worth > worrying about... > Hey: thanks for the benchmark, but please don't think it's useless just because it's monior PHP is a web program language, let's think about a high trafiic site, which get 100, 000, 000 pv perday. 100, 000, 000 * 0.0000005 = 500s perday and inefficent not always means performance only, in this case , you need to define various functions for different regexs if you use loop style. and do you prefer array_walk or foreach when you try to iteraterly process an array? thanks > > My $0.02 at least... > > Anthony > -- Laruence Xinchen Hui http://www.laruence.com/