On Sat, May 4, 2013 at 4:31 PM, Laruence <larue...@php.net> wrote: > I made a RFC for this: > https://wiki.php.net/rfc/second_arg_to_preg_callback > > Note that giving meaning to an extra argument in existing callbacks constitutes a small BC break in at least two cases:
1) function myhandyfunction($v, $arg = 42) { .. } preg_replace_callback([..., ...], "myhandyfunction", ..) here $arg will no longer be 42 after this change. 2) Most internal functions do not accept extra arguments, and thus will suddenly raise a notice if used as callbacks. It might be worth mentionning this in the RFC. > thanks > > > > > On Sat, May 4, 2013 at 10:28 PM, Laruence <larue...@php.net> wrote: > > > > > > > > > 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/ > > > > > > -- > Laruence Xinchen Hui > http://www.laruence.com/ > -- Etienne Kneuss http://www.colder.ch