Direct method call slower than method_exists()

php.internals

David Rodrigues

8 years ago
I have take note that a lot of projects (like Laravel) prefer uses method_exists() than implements an empty function (that should be useful to IDE when it is not annotated as an @method on class). For some reason, method_exists() will works faster than direct call when method doesn't exists vs. a direct method call when method is empty. My benchmarks: Case #1: * Direct call, empty method: * Cycles by min. : 26.459.804 Case #2: * Direct call, simple content (eg. is_bool(true)): * Cycles by min. : 24.771.454 - 6.38% slower than Case #1 Case #3: * method_exists(), no method: * Cycles by min. : 45.014.690 - 70.12% faster than Case #1 Case #4: * method_exists(), method exists with simple content: * Cycles by min. : 18.068.555 - 27.06% slower than Case #2 You will note that method_exists() will be more useful when method doesn't exists (+70% faster), but worse in cases where it does (27% slower). Which make that a hard decision, because you need "guess" the method declaration usage when implements something like that. If case the method existence is very low, then you will prefer method_exists(), which is bad for code design. My suggestion here (that I don't know if could be applied as is): identify empty methods and avoiding the execution (once that it will not do anything anyway). So we could just implement empty methods without any problem. Maybe it could be done at this point and related: https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L725
-- David Rodrigues

Nikita Popov

8 years ago
On Thu, Mar 8, 2018 at 6:41 PM, David Rodrigues <david.proweb@gmail.com> wrote:
> I have take note that a lot of projects (like Laravel) prefer uses > method_exists() than implements an empty function (that should be useful to > IDE when it is not annotated as an @method on class). > > For some reason, method_exists() will works faster than direct call when > method doesn't exists vs. a direct method call when method is empty. > > My benchmarks: > > Case #1: > * Direct call, empty method: > * Cycles by min. : 26.459.804 > > Case #2: > * Direct call, simple content (eg. is_bool(true)): > * Cycles by min. : 24.771.454 > - 6.38% slower than Case #1 > > Case #3: > * method_exists(), no method: > * Cycles by min. : 45.014.690 > - 70.12% faster than Case #1 > > Case #4: > * method_exists(), method exists with simple content: > * Cycles by min. : 18.068.555 > - 27.06% slower than Case #2 > > You will note that method_exists() will be more useful when method doesn't > exists (+70% faster), but worse in cases where it does (27% slower). Which > make that a hard decision, because you need "guess" the method declaration > usage when implements something like that. If case the method existence is > very low, then you will prefer method_exists(), which is bad for code > design. > > My suggestion here (that I don't know if could be applied as is): identify > empty methods and avoiding the execution (once that it will not do anything > anyway). So we could just implement empty methods without any problem. > > Maybe it could be done at this point and related: > https://github.com/php/php-src/blob/master/Zend/zend_ > language_parser.y#L725 > > -- > David Rodrigues
Could you please provide the used benchmarking code? Nikita

David Rodrigues

8 years ago
Case #1: https://pastebin.com/cT0gWuNH Case #2: https://pastebin.com/724v9rBZ Case #3: https://pastebin.com/9zXpztCc Case #4: https://pastebin.com/q87p9S4r 2018-03-08 14:52 GMT-03:00 Nikita Popov <nikita.ppv@gmail.com>:
> On Thu, Mar 8, 2018 at 6:41 PM, David Rodrigues <david.proweb@gmail.com> > wrote: > >> I have take note that a lot of projects (like Laravel) prefer uses >> method_exists() than implements an empty function (that should be useful >> to >> IDE when it is not annotated as an @method on class). >> >> For some reason, method_exists() will works faster than direct call when >> method doesn't exists vs. a direct method call when method is empty. >> >> My benchmarks: >> >> Case #1: >> * Direct call, empty method: >> * Cycles by min. : 26.459.804 >> >> Case #2: >> * Direct call, simple content (eg. is_bool(true)): >> * Cycles by min. : 24.771.454 >> - 6.38% slower than Case #1 >> >> Case #3: >> * method_exists(), no method: >> * Cycles by min. : 45.014.690 >> - 70.12% faster than Case #1 >> >> Case #4: >> * method_exists(), method exists with simple content: >> * Cycles by min. : 18.068.555 >> - 27.06% slower than Case #2 >> >> You will note that method_exists() will be more useful when method doesn't >> exists (+70% faster), but worse in cases where it does (27% slower). Which >> make that a hard decision, because you need "guess" the method declaration >> usage when implements something like that. If case the method existence is >> very low, then you will prefer method_exists(), which is bad for code >> design. >> >> My suggestion here (that I don't know if could be applied as is): identify >> empty methods and avoiding the execution (once that it will not do >> anything >> anyway). So we could just implement empty methods without any problem. >> >> Maybe it could be done at this point and related: >> https://github.com/php/php-src/blob/master/Zend/zend_languag >> e_parser.y#L725 >> >> -- >> David Rodrigues > > > Could you please provide the used benchmarking code? > > Nikita >
-- David Rodrigues

=?utf-8?B?5rGf5rmW5aSn6Jm+5LuB?=

8 years ago
What are you trying to prove? We all know method call is expensive. So definitely it will be slower when you make more calls. Best regards, CHU Zhaowei

David Rodrigues

8 years ago
I don't want to prove nothing, just thinking if is possible optimize empty methods to be faster than method_exists(). Em 10 de mar de 2018 1:11 AM, "CHU Zhaowei" <me@jhdxr.com> escreveu: