Re: [PHP-DEV] High performance function autoloading

This is only part of a thread. view whole thread
  105760
May 20, 2019 18:42 theodorejb@outlook.com (Theodore Brown)
On Mon, May 20, 2019 at 1:00 PM Gabriel O <gadelat@gmail.com> wrote:

> > Every time function autoloading been brought up in the past, there > > have been concerns about performance issues when calling a global > > function from inside a namespace. E.g. calling `strlen` in a loop > > would become far slower if every call has to trigger the autoloader. > > This trick for perf improvement is overblown. It's misconception that it > does provide speed advantage for most functions and reasons behind it. It > does so only for those implemented as opcodes. People started to abuse it > by importing ALL functions. Such overzealous approach completely prevents > useful things like function mocking.
Can you clarify? I'm not sure what performance improvement trick you are referring to, or what you mean by "importing all functions". Are you saying it's a misconception that triggering an autoloader on unqualified function calls in a namespace will slow down performance? As I understand it, this is the roadblock for function autoloading. Best regards, Theodore
  105765
May 20, 2019 19:36 gadelat@gmail.com (Gabriel O)
On 20. May 2019, at 20:42, Theodore Brown <theodorejb@outlook.com> wrote:
> > Can you clarify? I'm not sure what performance improvement trick you > are referring to, or what you mean by "importing all functions". Are > you saying it's a misconception that triggering an autoloader on > unqualified function calls in a namespace will slow down performance? > As I understand it, this is the roadblock for function autoloading. > > Best regards, > Theodore
Yes, this is misconception. Namespace resolutions are cached. First fixer tool bringing support for this was correct: PHP-CS-Fixer auto imports only optimized functions for this very same reason.
> On 20. May 2019, at 20:45, Marco Pivetta <ocramius@gmail.com> wrote: > > Disabling function mocking is good ©️ > > It was a terrible practice in first place, and it is usually done for > impure functions that should be wrapped in integration-tested adapters.
…which dramatically affects design of code. Nobody builds injectable replacements for these calls. As always, you are speaking from POV of library maintainer. As a user of your library, you don’t have perfect design. Nobody has. As a user of the library, I want to have ability to replace every aspect of it without copying it, while preserving simplicity - this is impossible to do, because these goals are in opposition. As a contributor of the library, I have found it impossible to write tests for some parts of very same library, because its code style guide dictates importing all the functions which makes it impossible to mock function call. And replacing them with injectable adapters was deemed overkill (and is subject of BC concerns). Anyways, it doesn’t matter. Disabling function fallback for all functions has very little benefit like I mentioned.
  105766
May 20, 2019 20:30 theodorejb@outlook.com (Theodore Brown)
On Mon, May 20, 2019 at 2:36 PM Gabriel O <gadelat@gmail.com> wrote:

> > Can you clarify? I'm not sure what performance improvement trick you > > are referring to, or what you mean by "importing all functions". Are > > you saying it's a misconception that triggering an autoloader on > > unqualified function calls in a namespace will slow down performance? > > As I understand it, this is the roadblock for function autoloading. > > Yes, this is misconception. Namespace resolutions are cached. First > fixer tool bringing support for this was correct: PHP-CS-Fixer auto > imports only optimized functions for this very same reason.
I'm confused, since this doesn't match what I've read elsewhere. For example, Nikita wrote the following last time function autoloading was discussed: [1]
> Calling the autoloader if a global function with the name exists will > totally kill performance. This means that every call to strpos() or > any of the other functions in the PHP standard library will have to > go through the autoloader first, unless people use fully qualified > names (which, currently, they don't). This is completely out of the > question.
In the same thread, it was suggested that a cache could be used to avoid repeatedly triggering the autoloader, but concerns were also pointed out with this: [2]
> > Of course calling e.g. strpos() should not trigger the auto-loader > > repeatedly - can we cache the information that the auto-loader was > > attempted once during the current script execution? so that e.g. > > only the first call to strpos() triggers the auto-loader? > > I think triggering it even once for every internal function in the > code may be too much. > > > I suppose it would still happen once for every namespace from which > > strpos() gets called, so maybe this optimization doesn't help much. > > Exactly. Also, caching stuff assumes static environment. What if it > changes, e.g. autoloader gets different configuration?
This is why I suggested the alternative of by default falling back to the global namespace for unqualified functions before triggering the autoloader, and allowing this fallback to be disabled for the rare case where functions in a namespace are spread across files and need to override a global function. I don't think this proposal changes anything related to function mocking. As you pointed out, libraries can already prevent mocking by importing or qualifying global function calls. Sincerely, Theodore [1]: https://externals.io/message/94895#94897 [2]: https://externals.io/message/94895#94956
  105769
May 21, 2019 08:16 gadelat@gmail.com (Gabriel O)
> On 20. May 2019, at 22:30, Theodore Brown <theodorejb@outlook.com> wrote: > > On Mon, May 20, 2019 at 2:36 PM Gabriel O <gadelat@gmail.com> wrote: >> >> Yes, this is misconception. Namespace resolutions are cached. First >> fixer tool bringing support for this was correct: PHP-CS-Fixer auto >> imports only optimized functions for this very same reason. > > I'm confused, since this doesn't match what I've read elsewhere. For > example, Nikita wrote the following last time function autoloading was > discussed: [1] > >> Calling the autoloader if a global function with the name exists will >> totally kill performance. This means that every call to strpos() or >> any of the other functions in the PHP standard library will have to >> go through the autoloader first, unless people use fully qualified >> names (which, currently, they don't). This is completely out of the >> question.
Check https://www.reddit.com/r/PHP/comments/b107c5/optimizing_your_php_app_speed/eim2lti <https://www.reddit.com/r/PHP/comments/b107c5/optimizing_your_php_app_speed/eim2lti> which is also comment from nikic. I guess there is some confusion core maintainers should clear up. Anyway, my point was if it improves perf of only some functions, this config should be named differently and not have impact on non-optimized ones.