max verstappen formula 1 car

What performance tricks actually work

Posted Mon Jul 23 2018

We've all been there before, you submit a pull request and moments later you get a comment like: "Hey you should use a native function here, they are so much faster" or "You can declare this final, that way we save some processing power".

It's great that we as developers keep an eye on this, but how true are these thing. And are they still a thing in newer PHP versions?

To the laboratory 

Time to put some of these "good practices" to the test. I've selected 10-speed tricks that I've picked up over the years and we're going to check how relevant they still are in PHP7.2.

So how are we going to test this? I've set up a small project that we are going to be running natively (no Docker, no vagrant) in MacOs (version: 10.13.5). The PHP version is the latest version currently on brew (PHP 7.2.8).

The benchmark itself uses PHPBench and we are going to compare each "trick" to its standard alternative. They are separate methods that each will be running 1000 times over 5 iterations. So that means we will run each test 5000 times grouped over 5 results. That way we can minimise deviations and extract meaningful results.

Sounds like fun? Let's bust some myths.

But before we begin, please a word of warning. We are going to zoom in on these claims. Some of these results might seem pretty high but that is only because we only run very small pieces of code. The results might not be that extreme in your day to day code.

Are single quotes faster than double quotes? 

Let's start out with a classic. As single quotes are encouraged by PSR we all might be getting some small speed bonuses without knowing it. We will test with this code:

And these are the results:

Turns out that single quotes are about 5% slower in this test.

is JSON faster than XML? 

Sometimes we like to use JSON or XML to setup validation or config files. Most people like to use JSON over XML due to readability reasons. But is it also faster?

A quick word of warning here, we will be using the native xmlrpc_encode en xmlrpc_decode functions. These are very experimental and not fully implemented. We could be using packages for this, something I would certainly advise in real projects, but that would skew the results too much (as we need to load them in etc). So here is the code:

And unsurprisingly here are the results:

The native experimental functions that deal with XML are way slower in our tests.

Using loads of layered objects is way slower? 

This one will be a bit messy to display. We are going to new up some classes and send the parameters down 3 layers. There we execute the same function as we otherwise would.

I think we all know that the new-ing up of classes will lose us some time, but let's see how much time we lose.

Unsurprisingly the new-ing up of classes takes some time. In this case, it comes down to about 25% slower. This obviously doesn't mean you shouldn't be using classes anymore. Personally, I will always prefer maintainability over speed.

Native array functions should be faster than loops, right? 

This is a classic. It's said that native array functions are faster than for each loop because they are native C functions. This is the code we will be running:

I'm going to be totally honest here and say that I've run this test a few times now, cause I couldn't really believe the results:

Turns out that in this test the array_map method is slower than the foreach. This probably has something to do with the anonymous function.

$row[’id’] is 7 times faster than $row[id] ? 

I've never heard of this one. Apparently, it's a thing:

Turns out it doesn't really make a lot of difference, at least not in the 700% range.

The string fetching is even marginally slower in our test by 2%.

Are throws super expensive? 

Error handling is an important part of any application, but it is said you should be a bit wary of using extensive amounts of try-catch blocks. Time to put it to the test.

And the results:

Unsurprisingly we lose some time on the errorHandling. But personally, I would always recommend having more error handling over having less.

What is the impact of unused vars? 

Most static analysis tools tend to either complain about unused vars or straight up to remove them for you.

As unused vars in your code serve no real benefit, it doesn't really make sense to keep them. That said, let's take a look at the cost.

and the results:

So it is about 7% in our tests. But as you probably know, there is no real reason to keep those vars around.

Magic methods are slower than regular ones? 

I love to use value objects. And in those objects, I normally use __toString() to cast the object to a string. But I've had some remarks that you should just make them yourself to have a speed boost. Time to take a look at that.

Turns out magic methods are indeed a tiny bit slower, at about 12% in this test.

Final classes should be faster than non-final classes? 

A friend of mine (the very talented Wouter Sioen) declares his classes final on the creation and only changes it when they really need to be extended.

I'm pretty sure he does that due to OOP reasons, but maybe it's also a bit faster. That could make sense right?

Turns out it does

In our tests, it is slightly faster to use final

That said, I think it a good thing to do anyway.

Do comments have an impact on your code? 

Ok, this is the last one. This has brought so many discussions in the past. Docblocks over return types, code should be self-documenting, ... You've seen the discussions before.

All of those Katy Perry facts result in:

About these tests 

Some of these tests might surprise you, some might not. That said, please don't stare yourself blind at the results here. Speed is just one part of software development, and I personally think marginal gains don't out weight good developer practices.

At least you left here with some fun facts about pop stars.

Hey thanks for reading!

Hope you enjoyed this post. There is no comments section here, if you've ever seen the YouTube comments section you'll probably understand why. If you have any remarks or comments on this topic, you can find links below to social media discussions

Mother board

Connect microservices with the help of GRPC

Posted Sun Jul 23 2017

Microservices can solve a lot of architectural problems, and sometimes create a few fun new ones. A big problem however is connecting these services to each other.Can GRPC lend a hand here?

Continue reading
Bird's eye view of a landscape

A bird's eye view on API development

Posted Sun Nov 15 2015

So you want to build a web API. You have to start somewhere, why not here

Continue reading
Laptop with code

How we improved our PWA score by 53 points in 4 hours

Posted Sun Mar 12 2017

After a recent burst of inspiration at PHPUK Sam and I ran an experiment to see how much we could improve our company site in just 4 hours. Turns out it was far easier than we expected

Continue reading