Re: Re: [PROPOSAL]Add second to callback of preg_replace_callback

From: Date: Sat, 04 May 2013 14:28:09 +0000
Subject: Re: Re: [PROPOSAL]Add second to callback of preg_replace_callback
References: 1 2 3 4 5 6 7  Groups: php.internals 
Request: Send a blank email to internals+get-67300@lists.php.net to get a copy of this message
On Sat, May 4, 2013 at 9:46 PM, Anthony Ferrara <ircmaxell@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/

« previous php.internals (#67300) next »