On Mon, Aug 11, 2014 at 10:09 PM, Andrea Faulds <a...@ajf.me> wrote:

>
> On 11 Aug 2014, at 08:36, Dmitry Stogov <dmi...@zend.com> wrote:
>
> > Hi Andrea,
> >
> > Could you measure the performance impact of function referencing.
> >
> > <?php
> > $func = "strlen";
> > for ($i = 0; $i < 10000; $i++) {
> >     $func("hello");
> > }
> > ?>
> >
> > vs
> >
> > <?php
> > $func = &strlen;
> > for ($i = 0; $i < 10000; $i++) {
> >     $func("hello");
> > }
> > ?>
>
> On my machine:
>
>     andreas-air:php-src ajf$ time sapi/cli/php ../funcref_a.php
>
>     real        0m0.043s
>     user        0m0.022s
>     sys 0m0.008s
>
>     andreas-air:php-src ajf$ time sapi/cli/php ../funcref_b.php
>
>     real        0m0.023s
>     user        0m0.015s
>     sys 0m0.006s
>
> I think the reason that function references are faster here is that it
> only has to do the hash table lookup once. If you tried to create a
> reference on each iteration and compared that to just using the string,
> then the string would be faster, as no memory needs to be allocated and
> deallocated for the closure.
>
> > I don't like the "&" syntax a lot, but I understand that it's a
> compromise between readability and implementation complication.
>
> Right. Myself, I’d prefer to just merge PHP’s namespaces and have $foo =
> func_name; work, but that wouldn’t work well and would break a lot of
> things.
>

may be:

$a = function strlen;

or

$a = function(stren);

but these are not excellent as well :(


> >
> > The patch probably misses support for "&self::foo", "&parent::foo",
> "&static::foo”.
>
> Good catch, I’ll try and get that implemented. Actually, I wonder if
> having &self::foo be bound to the object using it would be a good idea.
> While I resisted for &$foo::bar (I don’t support that syntax anyway), there
> might be some merit in it after all. If it would bind for you, you could
> always remove the binding or change it if it would be a problem.
>
> > It also may be improved using run_time cache (this is not important now).
>
> That’s something I wanted to do (might solve the performance problems with
> using & on each iteration), but I’m not sure quite what the right way to
> implement that is. In particular, what kind of cache (some sort of hash
> map?), how to index it (function name? fully-qualified function name?) and
> where to put it. I suppose I could just add a zval pointer to zend_function
> itself, but that would add eight bytes to every single function, which
> would add up.
>
> Actually, on a related note: Currently & creates a new closure on each
> use, and in PHP closures are compared by identity, not by their value.
> Perhaps we should change that so it checks for the same scope, this_ptr and
> implementation? Having &strlen === &strlen would probably be a good thing,
> it’s the more intuitive thing at least. Comparing the this_ptr of the two
> would be easy, however I have no idea whether you could compare the two
> zend_functions and have it work properly. You can’t just do an == in the C
> code, as closures embed and modify the zend_function.
>

I may implement this part if the RFC will be accepted.
Actually, most of the code may be just copy-pasted from
ZEND_INIT_STATIC_METHOD_CALL.

Thanks. Dmitry.


> --
> Andrea Faulds
> http://ajf.me/
>
>
>
>
>

Reply via email to