DEV Community

loading...

Optimizing your PHP app speed

elabftw profile image eLabFTW Updated on ・3 min read

speedy gonzales

This post is intended for PHP devs. I'll show you four ways to improve the speed of your PHP app easily. I'll skip the part where I tell you to use PHP 7, you must know by now that the speed improvement is dramatic… (and PHP 5.x is EOL anyway so…)

TL;DR: -a flag for composer, use opcache, use template engine cache, use fully qualified function names.

0. Use Composer optimization

The prod and dev environments are a little bit different. It shouldn't be a surprise to you if I tell you that you should not install the dev dependencies in prod, right?

composer install --no-dev
Enter fullscreen mode Exit fullscreen mode

That's basic. But did you know you can optimize the autoloader? Because the classes won't be changing once it's deployed, you can add a flag to composer (-a) that will improve the speed of autoloading:

composer install --no-dev -a
Enter fullscreen mode Exit fullscreen mode

Ok, but what does it do you'll ask?

From the help it says: "the Composer autoloader will only load classes from the classmap". It also implies "optimize-autoloader" so you don't have to add it too. You can see it as a way to say "hey, no more classes will be added so you don't need to scan the filesystem for a new class, just use the ones in the autoloader".

1. Use opcache

When a PHP file is read, it is converted in opcode, and then executed by the engine. Because in prod your PHP files won't change, you don't want to convert them to opcode every single time. Enter opcache.

Using opcache can dramatically increase the speed of your PHP application. Make sure that opcache_enable=1 is uncommented in your php.ini file. It will store the opcode for the executed files.

But don't enable it in your dev environment ;) (unless you enable opcache.validate_timestamps and set opcache.revalidate_freq to 0 (thx u/iluuu))

I recommend the opcache-status tool to monitor the use of opcache (at least in the beginning).

opcache-status

2. Use a template engine with cache

Templating engines like Twig can create a cache of the generated PHP code. The speed gain here can be dramatic. Again, you only want to cache the templates in prod, not in dev. But make sure that the cache is setup. For Twig see the documentation.

3. Qualify standard functions

Normally your code is namespaced (right?). So what happens when you call a function from the standard PHP library? The "compiler" (opcode producer) will look into the current namespace, then go up, and eventually use the global namespace. This means that if you add a "\" in front of standard functions (so effectively namespacing it in the global namespace explicitely), it will result in less opcode instructions, and that means faster code execution. Think it's one of those useless micro-optimization like the use of single vs. double quotes? You're correct, your app won't suddenly be faster (only very marginally), but if we can save CPU cycles, why not do it?

Note also that I prefer to add use function count; (for the count() function) in the use block, it's prettier than using \.

Conclusion

The little things I'm showing in this post won't make your app faster, at best it'll improve marginally. You can consider them as "good practice" because why not take some speed gains if you can, but if you want to get serious about optimizing your PHP app, get a profiler and optimize your SQL queries, because that's what is causing an issue, not the few milliseconds you might get with this kind of things ;)

That's all folks, have fun coding!

And if you like PHP, I'm always happy with contributions on the eLabFTW project, an open source electronic lab notebook. =)

Discussion (22)

pic
Editor guide
Collapse
ddziaduch profile image
Damian Dziaduch

You should really start with checking you SQL queries. You can have ultra fast code, but usually the problem are the queries... And other external calls like APIs. You should really focus on that first 🙂

Collapse
elabftw profile image
eLabFTW Author

Yes sure, but this is not what this post is about ;)

But maybe I can add a sentence saying that all of this won't make your code magically fast and one needs to use profilers and optimize SQLs to get serious.

Collapse
jorgecc profile image
Jorge Castro • Edited

Use a backslash in front of standard functions

Apparently, It butthurt so much on Reddit. However, it works.

This also works: (instead of \count) (PHP 5.6 and higher)

use function count;
Collapse
elabftw profile image
eLabFTW Author

Yeah, I made a lot of angry redditors :p But that's not a surprise. Most of the posts on r/php or r/programming are downvoted to oblivion, at least this one got a few tens of upvotes :)

Collapse
goodevilgenius profile image
Dan Jones

The "compiler" (opcode producer) will look into the current namespace, then go up, and eventually use the global namespace.

So, once it's compiled, wouldn't there be no performance difference between \count and count?

So, if I use your first suggestion, I don't need your last suggestion.

And if I use opcache_compile_file on all my PHP files during deployment, an end-user never hits an uncompiled file.

Collapse
jdreesen profile image
Jacob Dreesen

Actually the explanation for point "3. Use a backslash in front of standard functions" is not entirely correct. Yes, there will be less opcode produced because PHP only needs to look at the global namespace, but this should barely be noticeable (and would be optimized by the OpCode-Cache on the second run anyways).

But the speed improvement shown in your benchmark does not result from this "less namespace lookup" thing, but from a compiler-optimized "count" function that will be used when calling it this way.

This only works for a handful of functions, though.
You can find the list here: github.com/FriendsOfPHP/PHP-CS-Fix...

Collapse
david_j_eddy profile image
David J Eddy

Nice article eLabFTW. The leading backslash for SPL functions also helps to avoid naming conflicts; the reason I first started using it myself. Nice to know there if a measurable positive perf. impact as well.

Collapse
mte90 profile image
Daniele Scasciafratte

about the last point what is the minimum php version required?

Collapse
david_j_eddy profile image
David J Eddy

Namespacing became part of PHP in 5.3. My guess would be >= 5.3 .

php.net/manual/en/language.namespa...

Collapse
elabftw profile image
eLabFTW Author

Anyway, if you're using anything less than 7.1 in 2019 you're doing something wrong :p

Thread Thread
jorgecc profile image
Jorge Castro

PHP 5.6 is discontinued but for practical purpose, PHP 5.6 is still alive and kicking so the community, projects, servers and so on. In fact, I have a project that uses php 5.2 and I can kill it neither upgrade. I can't upgrade because they don't pay me for it, and I can kill it because the customer is happy with it.

Thread Thread
juanitomint profile image
Juan Ignacio Borda

Legacy projects can be a pain in the ass that's why IBM is contributing to the 5.x branch of php to give developers and customers time to adapt and migrate, but EOL means it will no longer get security updates or fixes

Thread Thread
jorgecc profile image
Jorge Castro

Yes but most customers follow :

If it ain't broke, don't fix it.

Thread Thread
juanitomint profile image
Collapse
sicklounet profile image
Brenier Arnaud

Thanks for the article ! I have been practicing PHP for a long Time but I never digged into performance details.

I have a question though, what did you use for the Benchmark you made with the blackslash ?

Collapse
elabftw profile image
Collapse
darkain profile image
Vincent Milum Jr

About that last point, it truly is a "micro-optimization", in that, odds are there are other areas that are in the orders of hundreds to thousands of times more CPU intensive within the code that could be optimized using better overall application logic. Micro-optimizations are things we put in that we think will make a difference that really don't in the grand scheme of things.

Measuring the impact of having the leading slash or not results in ~1-8ms better performance across one-million executions. With such a minor difference in performance, a developer's time would honestly be better spent on more significant portions of the application.

3v4l.org/QaY2t

Collapse
darkain profile image
Vincent Milum Jr

Doing further investigating, it is actually MORE impactful to not use namespaces at all. If you are not actively within a namespace, and you don't use the leading \, then you get even more "micro-optimization" out of your code! ;)

3v4l.org/tmJMq

Collapse
stilldreaming1 profile image
still-dreaming-1

I timed running the entire test suite for the website I work on (not speed tests, functionality tests).

Then I ran some PHP-CS-Fixer rules to add backlashes before native functions and constants throughout our entire codebase. Then I timed the test suite again, and it was basically the same speed (technically it ran slightly slower with the backslashes).

Collapse
elabftw profile image
eLabFTW Author

Yes, I'm pretty sure opcache is making those changes pointless ;)

Collapse
ardhityawiedhairawan profile image
Ardhitya Wiedha Irawan

Nice article. I never use Opache before, I'll try it. Thank mate.

Collapse
nomadzy profile image
Achraf

Good to know, but if the php code performance is really important you can use phalcon framework