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...

My $0.02 at least...

Anthony

Reply via email to