11

PHP 7 is slowly unrolling and people start working with it, and so am I.

One of the new features in PHP7 is that you can give functions a type declaration for the inputs, and a type declaration for the result.

Example, one input must be a string, one an int and the result will be boolean:

// PHP <7
function foo($example, $someNumber) {}
// PHP 7
function foo(string $example, int $someNumber): bool{}

without declare(strict_types=1) I know that when you insert the wrong type, it gets converted. If you would enter a number for $example, it will be converted to string. If you add a float number as $someNumber, it will be converted to a round number. With the decleration, you get a type error.

Apart from possible "best practices", would updating my code with the type declarations improve the performance of the code? I reckon it could because I'm now telling the interpreter what to expect, but it might also add an extra type check.
Would it be worth the effort and time to update these functions?

Martijn
  • 15,791
  • 4
  • 36
  • 68
  • 5
    A large part of type hints is that they're a help *for the programmer*. With the right tools (intelligent IDEs, static type checkers), you can avoid whole classes of errors before your code even runs. Since PHP isn't typically compiled ahead of time, there probably won't be as many performance improvements as a static compiler would do. – deceze Jul 12 '16 at 07:20

1 Answers1

23

Ultimately, performance should not be your concern when adding type declarations. They exist to make the programmer's life easier, not the interpreter's. Use them if you think they will be helpful to you. Whether or not you use type declarations is unlikely to be the main determiner of your code's performance.

With that being said, currently (PHP 7.0) there is actually a small performance penalty when type declarations are used, because PHP now has to check the types of the values you pass in and out of functions. It is faster to not check at all, which is what happens when you don't have a type declaration.

However, it's a bit more nuanced than that, and the situation is changing.

Strict typing forces you to pass the correct types

If you're using strict typing, you have to pass a value of the ideal type (e.g. int), rather than being able to pass some other type (e.g. string) and have PHP convert it for you. Passing the correct type is faster than having PHP convert from some other type for you: type conversions take time.

Type declarations can avoid repeated type conversions

If you use type declarations, whether with strict typing or not, you usually avoid repeated type conversions for the same value.

Normally, if you have a function that does several number operations, and you pass in a string argument, PHP will have to convert it to the appropriate number type (int or float) each time it does an operation with it.

But if you have a type declaration on that argument, it gets converted only once, either automatically (weak typing mode) or because you explicitly converted it yourself.

Type declarations enable PHP to elide type-checks

Type declarations give your PHP runtime guarantees that it can sometimes use to avoid type checks it otherwise has to do. For example, take the following line of code:

$a = $b * $c;

Without type declarations, PHP first has to do an internal type check on $b and $c before it can actually multiply them; PHP needs to make sure they're both number types, convert them if they're not, and then perform the appropriate type of multiplication (int×int, float×int, etc.).

But if you've declared the types of $b and $c beforehand, then PHP doesn't need to check them here, and can immediately do the actual multiplication. That's faster. This is especially true if you do multiple operations with these variables inside the function.

This optimisation is implemented in PHP 7.1 when using OPcache.

Similar optimisations can be implemented to get rid of argument and return value type checks, too. For example, if one function declares a parameter is an int, there's no need to check its type again if it then passes that argument to another function which also expects an int. PHP 7.1 can currently drop some unnecessary return type checks (and more when using OPcache), but not argument type checks.

Because of these types of optimisations, the performance penalty for code with type declarations is getting smaller, and there's considerable potential for code with type declarations to be faster than code without in future.

Andrea
  • 19,134
  • 4
  • 43
  • 65
  • 2
    PHP 7.1 can remove some return type checks, but argument checks are currently not elided. – NikiC Sep 18 '16 at 18:43
  • Regarding "This optimisation is implemented in PHP 7.1 when using OPcache", do you have any sources for that or did you go through the C code to find that? And if I understand your answer correctly, in PHP 7.1 the performance *penalty* is reduced with OPCache but it is still overall a penalty compared to code without type declarations. Do you know if the situation is the same for PHP 7.2? – rink.attendant.6 Feb 23 '18 at 20:29
  • @rink.attendant.6 There's been a bit written about it by Dmitry Stogov on the PHP internals mailing list IIRC, but I'm not sure how to locate it. – Andrea Feb 25 '18 at 01:30