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