I do not want to remove early binding. In fact I always
wanted to have early binding as much as possible. Because
that is faster and makes compiler caches easier. So why slow
down stuff? A Compiler cache wants everythign as static as
possible which means a compiler cache wants early binding.
This is also faster. So what are you proposing here?
As I already explained, early binding may not work for cached code,
because of cross file dependencies.
My patch allows to delay early binding from file-compile-time to
file-load-from-cache-time.
Thanks. Dmitry.
Hello Dmitry,
Friday, March 14, 2008, 5:08:18 PM, you wrote:
I do not want to remove early binding. In fact I always
wanted to have early binding as much as possible. Because
that is faster and makes compiler caches easier. So why slow
down stuff? A Compiler cache wants everythign as static as
possible which means a compiler cache wants early binding.
This is also faster. So what are you proposing here?
As I already explained, early binding may not work for cached code,
because of cross file dependencies.
My patch allows to delay early binding from file-compile-time to
file-load-from-cache-time.
But that means we are compiling inheritance when a file is loaded form
the cache. The goal should be to compiling inheritance when writing to
the opcode cache file. All we achieve here is a slow down. If there is
something that makes this required than at least we need to warn the user
about the slow code. I Think what we need to do is deprecating class and
namespace use in non main blocks as well as include and require in non
main blocks. And if there is no such case than everything can be bound
early which is the fast state we should aim for.
Best regards,
Marcus
But that means we are compiling inheritance when a file is loaded form
the cache. The goal should be to compiling inheritance when writing to
the opcode cache file. All we achieve here is a slow down. If there is
You can not do that. You do not know that until runtime.
something that makes this required than at least we need to warn the user
about the slow code. I Think what we need to do is deprecating class and
It won't be slow. It would be much faster (in some cases 10x faster).
This specific assembly of instructions might be slower in some cases,
but the code altogether will be faster. That's the idea of the opcode
caches.
namespace use in non main blocks as well as include and require in non
main blocks. And if there is no such case than everything can be bound
early which is the fast state we should aim for.
We do not need to deprecate anything, and inheritance can not be bound
before parent class is known, which in the case of bytecode cache means
- not before the file is loaded from the cache. That's exactly what this
patch enables. It does not change performance characteristics of neither
cached not non-cached code, it just makes it much simpler and working in
all cases.
--
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Hello Stanislav,
Friday, March 14, 2008, 5:51:49 PM, you wrote:
But that means we are compiling inheritance when a file is loaded form
the cache. The goal should be to compiling inheritance when writing to
the opcode cache file. All we achieve here is a slow down. If there is
You can not do that. You do not know that until runtime.
something that makes this required than at least we need to warn the user
about the slow code. I Think what we need to do is deprecating class and
It won't be slow. It would be much faster (in some cases 10x faster).
This specific assembly of instructions might be slower in some cases,
but the code altogether will be faster. That's the idea of the opcode
caches.
namespace use in non main blocks as well as include and require in non
main blocks. And if there is no such case than everything can be bound
early which is the fast state we should aim for.
Lemme just think, doing inheritance at compile time before we send the stuff
to an opcode cache can be slower then? How is that possible? After all late
binding means we do it at run time. And no matter how much faster we can do
it. It will always be slower than doing the same thing only once.
We do not need to deprecate anything, and inheritance can not be bound
before parent class is known, which in the case of bytecode cache means
- not before the file is loaded from the cache. That's exactly what this
patch enables. It does not change performance characteristics of neither
cached not non-cached code, it just makes it much simpler and working in
all cases.
Inheritance cannot be done before the parent class is known. We still need
to do the prototype checks even if we assume the class is there and insert
a virtual class as parent somehow.
Best regards,
Marcus
Marcus Boerger wrote:
Hello Stanislav,
Friday, March 14, 2008, 5:51:49 PM, you wrote:
But that means we are compiling inheritance when a file is loaded form
the cache. The goal should be to compiling inheritance when writing to
the opcode cache file. All we achieve here is a slow down. If there isYou can not do that. You do not know that until runtime.
something that makes this required than at least we need to warn the user
about the slow code. I Think what we need to do is deprecating class andIt won't be slow. It would be much faster (in some cases 10x faster).
This specific assembly of instructions might be slower in some cases,
but the code altogether will be faster. That's the idea of the opcode
caches.namespace use in non main blocks as well as include and require in non
main blocks. And if there is no such case than everything can be bound
early which is the fast state we should aim for.Lemme just think, doing inheritance at compile time before we send the stuff
to an opcode cache can be slower then? How is that possible? After all late
binding means we do it at run time. And no matter how much faster we can do
it. It will always be slower than doing the same thing only once.We do not need to deprecate anything, and inheritance can not be bound
before parent class is known, which in the case of bytecode cache means
- not before the file is loaded from the cache. That's exactly what this
patch enables. It does not change performance characteristics of neither
cached not non-cached code, it just makes it much simpler and working in
all cases.Inheritance cannot be done before the parent class is known. We still need
to do the prototype checks even if we assume the class is there and insert
a virtual class as parent somehow.
I don't actually see early binding as being much of a problem, the real
problem is when the same class is both early and late bound. If you
consistently always bind early or always bind late, opcode caches should
be quite happy to let you do that. But if you mix the two, things get
chaotic and the problem becomes intractable. We went through all this
in APC a couple of years ago. My initial, somewhat naiive attempt at
fixing it:
http://news.php.net/php.pecl.cvs/4288
That obviously wasn't enough to fix it, so essentially we end up simply
detecting the scenario and not doing early binding for classes that are
detected to also be bound late:
http://pecl.php.net/bugs/bug.php?id=5314
-Rasmus
I don't actually see early binding as being much of a problem, the real
problem is when the same class is both early and late bound. If you
consistently always bind early or always bind late, opcode caches should
be quite happy to let you do that. But if you mix the two, things get
That's what we try to do in this patch - to make cache able to change
the binding mode.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
I don't actually see early binding as being much of a problem, the real
problem is when the same class is both early and late bound. If you
consistently always bind early or always bind late, opcode caches should
be quite happy to let you do that. But if you mix the two, things get
chaotic and the problem becomes intractable. We went through all this
in APC a couple of years ago. My initial, somewhat naiive attempt at
i'm not sure why i can't reproduce it years ago with apc enabled and i
reproduce it with a complex script later.
a1.php
class a { function aMethod() { echo FILE; } }
a2.php
class a { function aMethod() { echo FILE; } }
child.php
class child extends a { }
main1.php which is requested first
include "a1.php";
include "child.php";
$child = new child()
$child->aMethod(); // aMethod() from a1.php, but what if i update
a1.php after child.php is cached?
main2.php which is requested later
include "a2.php";
include "child.php";
$child = new child();
$child->aMethod(); // aMethod() from a1.php because of early binding
is done before cache? or from a2.php?
with and without opcode cacher, what is echo'ed if you requests main1
first and main2 later?
with the delayed early binding, php behavior exactly the same with
opcode cachers enabled or disabled
imho, with delayed early binding, every class is binded once when
there is no opcode cacher, and opcode cacher can even decide to call
bind api before cache.
looks like we can always the delay the binding unless we want binary
back compatbility for 3rd party modules? correct me if i'm wrong