We’ve been having quite a few issues with speed and server load, something which we’d never had to worry about in the past. We’ve been building more and more web apps and fewer and fewer simple websites.
We are also facing mod security restrictions on our webhost. Cartika (no longer recommended) are strapped down pretty tightly, but that makes sense. They also let us know right away if a website of ours is facing security attacks or if it is being scraped every day.
Apparently not all PHP is created equal and it is time to batten down the hatches.
Once we get to functionality we will have to put a full-fledged optimisation phase in the development cycle: the Code Optimization Phase.
In that phase we will specifically target PHP speed and security (as functionality will already be completely in place).
I will start by asking all Foliovision developers to read the article 40 Tips for optimizing your php Code. The top twenty or so are below.
- If a method can be static, declare it static. Speed improvement is by a factor of 4.
- echo is faster than print.
- Use echo’s multiple parameters instead of string concatenation.
- Set the maxvalue for your for-loops before and not in the loop.
- Unset your variables to free memory, especially large arrays.
- Avoid magic like __get, __set, __autoload
- require_once() is expensive
- Use full paths in includes and requires, less time spent on resolving the OS paths.
- If you need to find out the time when the script started executing, $_SERVER[’REQUEST_TIME’] is preferred to time()
- See if you can use strncasecmp, strpbrk and stripos instead of regex
- str_replace is faster than preg_replace, but strtr is faster than str_replace by a factor of 4
- If the function, such as string replacement function, accepts both arrays and single characters as arguments, and if your argument list is not too long, consider writing a few redundant replacement statements, passing one character at a time, instead of one line of code that accepts arrays as search and replace arguments.
- It’s better to use select statements than multi if, else if, statements.
- Error suppression with @ is very slow.
- Turn on apache’s mod_deflate
- Close your database connections when you’re done with them
- $row[’id’] is 7 times faster than $row[id]
- Error messages are expensive
- Do not use functions inside of for loop, such as for ($x=0; $x < count($array); $x) The count() function gets called each time.
- Incrementing a local variable in a method is the fastest. Nearly the same as calling a local variable in a function.
- Incrementing a global variable is 2 times slow than a local var.
- Incrementing an object property (eg. $this->prop++) is 3 times slower than a local variable.
Alec Kinnear
Alec has been helping businesses succeed online since 2000. Alec is an SEM expert with a background in advertising, as a former Head of Television for Grey Moscow and Senior Television Producer for Bates, Saatchi and Saatchi Russia.
Interesting stuff and some great tips, but I believe not all is valid.
For example, number 2 “echo is faster than print” whilst this may be fractionally true (it seriously does not make a huge difference, in fact, I believe echo will become an alias of print in later PHP versions) there are better considerations like using single quotes rather then double quotes on a string. The use of double quotes is mentioned in the other article you link to, however, it says “Of course you can only do this when you don’t need to have variables in the string.” but doesn’t mention that concatenation is much faster than trying to put variables inside a double quote string. HEREDOC also has a terrible overhead.
17 $row[’id’] is 7 times faster than $row[id] USING $row[id] IS WRONG Please see ‘http://uk3.php.net/manual/en/language.types.array.php’
I’m also interested in this: 18. “Error messages are expensive” Do you mean displaying an error message is expensive, or having a script that doesn’t work is expensive?
Thanks for the tips James.
What I mean by “Error messages are expensive” is that each error message generates a lot of overhead with log writing and recovery. It’s like a sound room with an echo.
If you get the code right in the first place, you’ll be able to use the processor for processing and not for error recovery.
In general, PHP, particularly PHP5 is becoming a much more efficient language with time so a lot of these issues will be resolved with better coding practice and stricter coding guidelines.
I agree – writing the code correctly in the first place is definitely the most effective; although dealing with errors in a smart way is also good.
I remember from when I used to do Java, discussions about (as an abstract example) is it more efficient to check if a variable is not zero, or just place the code in a try catch block (and catch the divide by zero error) – it would be interesting to see if similar principles apply to PHP5?
(obviously you can see that the discussion would go on, as the debate ranges from should you purposely write code that would throw an error, or is throwing an error an acceptable coding practice!? I don’t think I ever concluded that one!)
Cheers, James.
Could you test this James, for PHP?
A few real world number for how many ticks it takes to handle an error in PHP versus a clean execution…
The issue with PHP is that one uses it to automate a lot of repetitive small tasks. Any error is like an echo chamber. But would be interestin to know exactly the cost.
2: The speed of both echo and print is fast and in comparisson to another functions that are commonly used in almost every PHP script, their speed difference doesn’t matter that much.
16: Closing of database connection is actually a serious discussion. For instance Microsoft encourage programmers to close connection to database after every pack of queries. This applies for .NET but databases are the same for .NET and PHP, so this is maybe a subject for another blog.
17: It is very, VERY bad practise to write string without quotes. Every strict programming language will throw error on this one. Everybody should avoid using this type of coding. (I know my words are strong, but proper coding practices are very important)
18: Error messages surely create a lot of overhead and good code should actually deal with all posible errors within itself. Exception handling was not introduced to PHP from the begginig, so PHP is not built to cope only with exceptions. Hopefully PHP crew will enhance their error handling in future, so more stable and reliable coding will be possible.