markrogoyski / math-php

Powerful modern math library for PHP: Features descriptive statistics and regressions; Continuous and discrete probability distributions; Linear algebra with matrices and vectors, Numerical analysis; special mathematical functions; Algebra
MIT License
2.33k stars 240 forks source link

Use qualified function calls for global functions or import them into namespaces #367

Closed Girgias closed 3 years ago

Girgias commented 4 years ago

Use \foo() instead of foo() for global functions.

The rationale is that it speeds up function resolution, and more importantly allows the PHP VM to use dedicated optimized opcodes for some of the functions (most notably \count()) instead of needing to resolve the function by using the global fallback (as it needs to check if the function hasn't been overwritten within the namespace) and then calling it.

The PHP-CS-FIXER tool (https://github.com/FriendsOfPhp/PHP-CS-Fixer) has the native_function_invocation fixer which can do this automatically , however this has a @risky mention as it would overwrite custom namespaced implementations.

An other, slightly more time consuming, solution is to explicitly import the global functions into namespaces by doing use function foo.

markrogoyski commented 4 years ago

Hi @Girgias,

Thanks for your interest in MathPHP and wanting to improve the performance.

I did a little research on this. I thought it might only affect the PHP compilation process into opcodes, which only happens once in modern PHP because of opcode caching, but it seems like the opcodes PHP produces may actually be slightly longer for PHP built-in functions when they are in a namespace, vs. when they are qualified to be the global built-in function. Interesting.

I would classify this as a micro-optimization. It technically makes things faster, but it would not be observable by any normal measurable means in normal usage, short of looping over the count() function a billion times.

Big wins improve performance much more than micro-optimizations. For example, improving the performance of matrix multiplication or linear regression by using better algorithms would bring significant, observable performance improvements. With time being limited, I have to choose where to focus, and would prioritize those kind of big wins over micro-optimizations.

That being said, I will do some more research into this because it is interesting, and if it continues to check out, I can add to the style guide for new code to qualify bulit-in PHP functions with the global \ namespace qualifier. However, I will defer updating existing code while there are still new features and other improvements that will bring more value for the time investment. I'll put this work at the bottom of the backlog to keep track of it for one day.

Thanks for the suggestion and information. Very interesting to see how PHP works under the hood.

Girgias commented 4 years ago

I agree this is more in the realm of micro optimization and that this is in no way high priority. I can also make a pull request adjusting the codebase if you want but I preferred opening an issue to discuss about it and how to incorporate it into the library.

markrogoyski commented 3 years ago

Hi,

This has been completed and merged into the main develop branch. Thanks for suggesting this improvement.

Mark