Object getter method optimization

php.internals

Lin Yo-An

10 years ago
Hello Everyone, I am recently trying to write an optimizer that could optimize the getter method call into just one object fetch opcode. I'd like to know thoughts from you guys, here is the note: https://c9s.hackpad.com/INLINE-OP-TVGo9WcshbZ
-- Best Regards, Yo-An Lin https://github.com/c9s

Dmitry Stogov

10 years ago
Hi Yo-An Lin, Unfortunately, this approach won't work. At first, at compile time we don't know the body of called getter. At second, the called method might be changed even at run-time, because of polymorphism. Tricks like this might be implemented using JIT and polymorphic inline caches. Thanks. Dmitry. ________________________________________ From: Lin Yo-An <cornelius.howl@gmail.com> Sent: Friday, March 18, 2016 05:23 To: internals Subject: [PHP-DEV] Object getter method optimization Hello Everyone, I am recently trying to write an optimizer that could optimize the getter method call into just one object fetch opcode. I'd like to know thoughts from you guys, here is the note: https://c9s.hackpad.com/INLINE-OP-TVGo9WcshbZ
-- Best Regards, Yo-An Lin https://github.com/c9s

Lin Yo-An

10 years ago
Hi Dmitry, Thanks for your reply! You're correct. let me try to explain your points: If I have a main.php and worker.php And I defined work($worker) { $status = $worker->getStatus(); } inside main.php when main.php is compiled, we don't know what the class entry of $worker is. What we only know is invoking a method "getStatus" on $worker CV unless we know we have to compile worker.php before main.php and add a type hint on $worker. Is it correct? Since the original approach doesn't work, here comes another new idea: When executing method call on an object, if we found the method body are just 2 op codes (FETCH_OBJ_R and RETURN), we then denote the method is a "getter method" And the next time, when we execute the same method, we found the "getter method" flag, we simply execute FETCH_OBJ_R on that object and return the value to avoid extra op code execution time. Do you think if this could work? Best Regards and Thanks for your work on PHP VM Yo-An Lin On Fri, Mar 18, 2016 at 3:36 PM, Dmitry Stogov <dmitry@zend.com> wrote:
> Hi Yo-An Lin, > > Unfortunately, this approach won't work. > At first, at compile time we don't know the body of called getter. > At second, the called method might be changed even at run-time, because of > polymorphism. > > Tricks like this might be implemented using JIT and polymorphic inline > caches. > > Thanks. Dmitry. > > ________________________________________ > From: Lin Yo-An <cornelius.howl@gmail.com> > Sent: Friday, March 18, 2016 05:23 > To: internals > Subject: [PHP-DEV] Object getter method optimization > > Hello Everyone, > > > I am recently trying to write an optimizer that could optimize the getter > method call into just one object fetch opcode. > > I'd like to know thoughts from you guys, here is the note: > https://c9s.hackpad.com/INLINE-OP-TVGo9WcshbZ > > -- > Best Regards, > > Yo-An Lin > https://github.com/c9s >
-- Best Regards, Yo-An Lin

Andrew Faulds

10 years ago
Hi Lin, Lin Yo-An wrote:
> Since the original approach doesn't work, here comes another new idea: > > When executing method call on an object, if we found the method body are > just 2 op codes (FETCH_OBJ_R and RETURN), we then denote the method is a > "getter method" > > And the next time, when we execute the same method, we found the "getter > method" flag, we simply execute FETCH_OBJ_R on that object and return the > value to avoid extra op code execution time. > > Do you think if this could work?
For a while I'd also been wondering if we could implement some implementation along these lines. Another approach could be possibly replacing such methods with an C implementation (though I don't know if non-internal classes can have internal methods). I don't know how successful it will be, but I'm interested to hear how much improvement it gives if you get it working. Thanks!
-- Andrea Faulds https://ajf.me/

Nikita

10 years ago
On Sat, 19 Mar 2016 23:40:09 +0300, Andrea Faulds <ajf@ajf.me> wrote:
> Hi Lin, > > Lin Yo-An wrote: >> Since the original approach doesn't work, here comes another new idea: >> >> When executing method call on an object, if we found the method body are >> just 2 op codes (FETCH_OBJ_R and RETURN), we then denote the method is a >> "getter method" >> >> And the next time, when we execute the same method, we found the "getter >> method" flag, we simply execute FETCH_OBJ_R on that object and return >> the >> value to avoid extra op code execution time. >> >> Do you think if this could work? > > For a while I'd also been wondering if we could implement some > implementation along these lines. Another approach could be possibly > replacing such methods with an C implementation (though I don't know if > non-internal classes can have internal methods). > > I don't know how successful it will be, but I'm interested to hear how > much improvement it gives if you get it working. > > Thanks!
I was playing with this idea sometime ago, it gives good performance boost for code like `for ($i = 0; $i < 100000; $i++) $a->getFoo();` but in the end of the day it's a very limited optimization. If you abstract away from getters and say you want to optimize more and more small functions like this one, you end up realizing that what you're actually doing is what JIT compilation would do in a more generic way.

Lin Yo-An

10 years ago
> > >> I was playing with this idea sometime ago, it gives good performance > boost for code like `for ($i = 0; $i < 100000; $i++) $a->getFoo();` but in > the end of the day it's a very limited optimization. > If you abstract away from getters and say you want to optimize more and > more small functions like this one, you end up realizing that what you're > actually doing is what JIT compilation would do in a more generic way.
I agree with you that JIT could achieve this. Although this could be done by JIT, however the JIT approach would require good code generation to produce efficient getter code to return the property value, and there will be a JIT threshold and extra compilation time for caller to reach.
> -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
-- Sent from Gmail Mobile

Dmitry Stogov

10 years ago
Hi Yo-An Lin, This "run-time inlining" approach may work. PHP compiler (or optimizer) may mark functions and methods suitable for "run-time" inlining (e.g. methods without arguments and FETCH_OBJ_R UNUSED, CONST -> TMP; RETURN TMP). Then INIT_METHOD_CALL may check this flag and execute "optimized code sequence" instead of pushing stack frame and real call. However, I'm not sure what kind of performance impact this may make, because we will have to make additional check on each INIT_METHOD_CALL execution. Thanks. Dmitry. ________________________________ From: Lin Yo-An <cornelius.howl@gmail.com> Sent: Saturday, March 19, 2016 10:08 To: Dmitry Stogov Cc: internals; Xinchen Hui Subject: Re: [PHP-DEV] Object getter method optimization Hi Dmitry, Thanks for your reply! You're correct. let me try to explain your points: If I have a main.php and worker.php And I defined work($worker) { $status = $worker->getStatus(); } inside main.php when main.php is compiled, we don't know what the class entry of $worker is. What we only know is invoking a method "getStatus" on $worker CV unless we know we have to compile worker.php before main.php and add a type hint on $worker. Is it correct? Since the original approach doesn't work, here comes another new idea: When executing method call on an object, if we found the method body are just 2 op codes (FETCH_OBJ_R and RETURN), we then denote the method is a "getter method" And the next time, when we execute the same method, we found the "getter method" flag, we simply execute FETCH_OBJ_R on that object and return the value to avoid extra op code execution time. Do you think if this could work? Best Regards and Thanks for your work on PHP VM Yo-An Lin On Fri, Mar 18, 2016 at 3:36 PM, Dmitry Stogov <dmitry@zend.com<mailto:dmitry@zend.com>> wrote: Hi Yo-An Lin, Unfortunately, this approach won't work. At first, at compile time we don't know the body of called getter. At second, the called method might be changed even at run-time, because of polymorphism. Tricks like this might be implemented using JIT and polymorphic inline caches. Thanks. Dmitry. ________________________________________ From: Lin Yo-An <cornelius.howl@gmail.com<mailto:cornelius.howl@gmail.com>> Sent: Friday, March 18, 2016 05:23 To: internals Subject: [PHP-DEV] Object getter method optimization Hello Everyone, I am recently trying to write an optimizer that could optimize the getter method call into just one object fetch opcode. I'd like to know thoughts from you guys, here is the note: https://c9s.hackpad.com/INLINE-OP-TVGo9WcshbZ
-- Best Regards, Yo-An Lin https://github.com/c9s -- Best Regards, Yo-An Lin