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. > > 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. -- Andrea Faulds http://ajf.me/ -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php