Hello,
with preloading and Composer, we don't need anymore to consider autoloading
for functions and/or constants. The reason is that basically Composer is
already doing a great job at loading functions: just give it a list of
files and it will ensure they are included all the time. Actually, Composer
is just an example, all similar "require all the time" strategies work.
The drawback of this approach used to be that requiring a bunch of
(potentially unused) files could be costly. But now that we have
preloading, this cost is zero. As such, autoloading functions/constants
would serve no purpose.
Then, we periodically have discussions about the rules for namespace
resolution of functions/constants. The fallback-to-root-namespace has no
measurable performance overhead - the cache is very effective. Yet, Nikita
has stated a few times that knowing the type of the arguments of the
function being called helps the engine a bit. With JIT, this might be
(/become) more important (is that correct, Dmitry and/or Nikita?)
I'm thus wondering: could we resolve the fallback-to-root-namespace rule at
preload time, for all preloaded implementations? For runtime-loaded code,
we would keep the current behavior.
In practice, this means that during development (when preloading is not
used), we would preserve all the hackability that the rule provides (PHP
being a hackable engine is a big PRO, here, this can help e.g. testing a
lot). The fallback-to-root-namespace is a wise pragmatic rule that serves
the language well IMHO. But in prod, in full-perf mode (aka when preloading
is enabled), this proposal would pave the way for better performance with
JIT, if confirmed.
WDYT?
Nicolas
PS: I fear I would be unable to implement anything related to this proposal
so I'm just sharing the idea to see if it could be interesting.
On Thu, Apr 23, 2020 at 6:59 PM Nicolas Grekas nicolas.grekas@gmail.com
wrote:
Hello,
with preloading and Composer, we don't need anymore to consider autoloading
for functions and/or constants. The reason is that basically Composer is
already doing a great job at loading functions: just give it a list of
files and it will ensure they are included all the time. Actually, Composer
is just an example, all similar "require all the time" strategies work.The drawback of this approach used to be that requiring a bunch of
(potentially unused) files could be costly. But now that we have
preloading, this cost is zero. As such, autoloading functions/constants
would serve no purpose.Then, we periodically have discussions about the rules for namespace
resolution of functions/constants. The fallback-to-root-namespace has no
measurable performance overhead - the cache is very effective. Yet, Nikita
has stated a few times that knowing the type of the arguments of the
function being called helps the engine a bit. With JIT, this might be
(/become) more important (is that correct, Dmitry and/or Nikita?)I'm thus wondering: could we resolve the fallback-to-root-namespace rule at
preload time, for all preloaded implementations? For runtime-loaded code,
we would keep the current behavior.In practice, this means that during development (when preloading is not
used), we would preserve all the hackability that the rule provides (PHP
being a hackable engine is a big PRO, here, this can help e.g. testing a
lot). The fallback-to-root-namespace is a wise pragmatic rule that serves
the language well IMHO. But in prod, in full-perf mode (aka when preloading
is enabled), this proposal would pave the way for better performance with
JIT, if confirmed.WDYT?
Nicolas
PS: I fear I would be unable to implement anything related to this proposal
so I'm just sharing the idea to see if it could be interesting.
Hey Nicolas,
I think this is something we should consider. Maybe not as default
behavior, but at least under an ini setting. Basically, any unqualified
call would get resolved to a global call or a namespaced call based on
which functions are declarated at preloading time.
I see one potential problem. If you have something like
namespace Foo;
if (true) {
function strlen($x) {}
}
strlen("foo");
then depending on how the preloading is performed, PHP will not be aware of
the "Foo\strlen" function. Specifically if opcache_compile_file()
preloading is used, because it does not execute code. If "require" based
preloading is used, this is not a problem.
Regards,
Nikita
Hello Nikita,
with preloading and Composer, we don't need anymore to consider autoloading
for functions and/or constants. The reason is that basically Composer is
already doing a great job at loading functions: just give it a list of
files and it will ensure they are included all the time. Actually,
Composer
is just an example, all similar "require all the time" strategies work.The drawback of this approach used to be that requiring a bunch of
(potentially unused) files could be costly. But now that we have
preloading, this cost is zero. As such, autoloading functions/constants
would serve no purpose.Then, we periodically have discussions about the rules for namespace
resolution of functions/constants. The fallback-to-root-namespace has no
measurable performance overhead - the cache is very effective. Yet, Nikita
has stated a few times that knowing the type of the arguments of the
function being called helps the engine a bit. With JIT, this might be
(/become) more important (is that correct, Dmitry and/or Nikita?)I'm thus wondering: could we resolve the fallback-to-root-namespace rule
at
preload time, for all preloaded implementations? For runtime-loaded code,
we would keep the current behavior.In practice, this means that during development (when preloading is not
used), we would preserve all the hackability that the rule provides (PHP
being a hackable engine is a big PRO, here, this can help e.g. testing a
lot). The fallback-to-root-namespace is a wise pragmatic rule that serves
the language well IMHO. But in prod, in full-perf mode (aka when
preloading
is enabled), this proposal would pave the way for better performance with
JIT, if confirmed.WDYT?
Nicolas
PS: I fear I would be unable to implement anything related to this
proposal
so I'm just sharing the idea to see if it could be interesting.Hey Nicolas,
I think this is something we should consider. Maybe not as default
behavior, but at least under an ini setting. Basically, any unqualified
call would get resolved to a global call or a namespaced call based on
which functions are declarated at preloading time.
An ini setting would work for me - I'd enable it all the time when using
preloading.
I see one potential problem. If you have something like
namespace Foo;
if (true) {
function strlen($x) {}
}
strlen("foo");then depending on how the preloading is performed, PHP will not be aware
of the "Foo\strlen" function. Specifically ifopcache_compile_file()
preloading is used, because it does not execute code. If "require" based
preloading is used, this is not a problem.
I see this as an inherent limitation to using opcache_compile_file()
. Class
aliases can lead to similar differences.
Not something I would care about, especially if there is an ini setting to
opt-in for the proposed behavior.
I'm unfortunately entirely reliant on you or someone else that has the
skills for implementing this...
Thanks for your answer and your interest in the proposal!
Nicolas