views:

1824

answers:

24

I'm looking for PHP Optimization tips. Coding practices and other methodologies which will make my PHP execute faster. One tip per answer, please, and include why it makes the code faster!

This is not about HTML or Javascript execution, but purely server side PHP execution.

+2  A: 

I enclose strings that doesn't contain variables with single quotes. This tells the compiler that it doesn't need to search for variables to replace.

echo 'This string is faster';
echo "This string is slower";
Jrgns
Actually no. PHP is clever enough to compile both into the same bytecode. It helps the parser only. If you have a clever optcode cache "$foo $bar" should be equally fast to $foo . ' ' . $bar.
Armin Ronacher
That said, most php applications run without opcode caching, so it is a good idea to use single quotes when you don't want to evaluate the sting and do variable substitution in it.
David
A: 

prefer require and include over thier _once counterparts

EDIT: added at request of commenter: because require_once requires checks to see if the file has been included before. Benchmark it yourself and you'll see its noticeably slower.

Marc Gear
Why is that faster?
Jrgns
Because require_once requires checks to see if the file has been included before. Benchmark it yourself and you'll see its noticably slower
Marc Gear
Put the explanation in the answer please.
Jrgns
But why would anyone require twice?
Joe Philllips
Require kills the script if the file is not found, include does not. *_once kills the script if it attempts to incl/req a file more than once. It uses a small cache to store filenames but is a very slight speed disadv. I continue to use their _once counterparts if I only need it once.
Ross
+4  A: 

There are dozens of small performance tweaks; For example:

$text = 'test'; is faster as $text = "test"; (because the double quote's parse variables) BUT: $text = "testing: $text"; is faster as $text = 'testing: ' . $text;

D4V360
Why? That didn't make any sense to me.
Joe Philllips
Just try it out with a microtime check; You'll see, parsing a string is faster as concatenating.
D4V360
I find $text = 'testing: ' . $text; more readable. But this depends on the editors syntax highlighting ability. (vim shows the inlined vars just fine)
Bob Fanger
A: 

use array_key_exists() to find values in arrays rather than in_array()

Marc Gear
That doesn't even make sense - in_array checks for values, array_key_exists checks for indexes/keys.
Nouveau
if you're just checking that a particular value exists in an array in_array() is a slow way to do it, array_key_exists(array_flip($array)) is likely to be faster.
Marc Gear
in_array is faster than array_flip + array_key_exists.$letters = range('a', 'b');for ($i = 0; $i < 100000; ++$i){ array_key_exists('f', array_flip($letters));}// time: 0.358922958374for ($i = 0; $i < 100000; ++$i){ in_array('f', $letters);}// time: 0.143461942673
David
Ok, it munged my example, but in_array is about twice as fast.
David
+1  A: 

the mysql extension is faster than the mysqli extention, which is (sometimes) faster than PDO.

If you use mysqli in conjunction with mysqlnd thats faster still

Marc Gear
Do you have any reference for that? I'd be interested in knowing.
David
Me too, a source would be killer to such a claim.
Till
[citation-needed]
Mez
http://myphpdigest.com/tutorial/Benchmark_-_MYSQL_vs_MYSQLi http://blogs.vinuthomas.com/2006/08/07/benchmark-mysql-mysqli-pdo-in-php/ http://dealnews.com/developers/php-mysql.html There are a bunch of others who have done benchmarks but i'd encourage you to do your own and see what works for you.
Marc Gear
A: 

Focus on optimising your database querying rather than your php, really.

gizmo
That doesn't realy answer the question, does it?
Jrgns
Yes it does. If you start wasting your time focusing on "optimizing tips" that may change from a revision of PHP to another, it's really useless comparing to CPU, memory and time you can gain on optimizing your database structure and querying.
gizmo
I've got an app which executes a LOT of PHP with minimal MySQL calls. I'm sure there's some apps that run without doing MySQL calls. Every little bit helps.
Jrgns
DB optimization is part of overall application optimization. Similarly, PHP (or insert-language-here) optimization is ALSO part of overall application optimization.So, when someone asks for "PHP optimization" tips, answers about DB optimization don't really answer the question. My two cents.
Peter Bailey
+14  A: 

40 Tips for optimizing your PHP code:

http://reinholdweber.com/?p=3

Here's a few from the list:

  1. If a method can be static, declare it static. Speed improvement is by a factor of 4.
  2. echo is faster than print.
  3. Use echo's multiple parameters instead of string concatenation.
  4. Set the maxvalue for your for-loops before and not in the loop.
  5. Unset your variables to free memory, especially large arrays.
  6. Avoid magic like __get, __set, __autoload
  7. require_once() is expensive
  8. Use full paths in includes and requires, less time spent on resolving the OS paths.
  9. If you need to find out the time when the script started executing, $_SERVER[’REQUEST_TIME’] is preferred to time()
  10. See if you can use strncasecmp, strpbrk and stripos instead of regex

    ...[snip]...

scunliffe
Aweome, thanx for adding the examples.
Jrgns
scunliffe, I'm sorry to say that your optimisation tips are actually increasing development effort. Static methods are declared static on purpose, and past PHP 6 calling static methods non-static way will cause errors. Unsetting variables is rarely needed in well structured program, (continued...)
Michał Rudnicki
where variables have local scope and are automatically purged. Magic methods are ok as long as you know how to use them. You can save yourself a lot of coding with implicit getters and setters. require_once is a time saver when you try to cope with circular dependencies. (continued...)
Michał Rudnicki
Autoloading is a fantastic feature that saves you from manual tracking includes and fixing your code after your co-programmer changed or added something. Full paths are nightmare if you deploy on serveral servers. Also, it's best option if you want the code developed in Windows to fail on UNIX.
Michał Rudnicki
@Michal no problem, I was just reporting the last source I'd read that sounded legit. Not all of them are correct, but most appear to be.
scunliffe
+1  A: 

Use a cached length value when iterating over arrays - this works across other languages too, and can give you significant speed gains if the set of elements you are iterating over is large or if the size calculation is complex.

$length = count($some_array)

for ($count = 0; $count < $length; $count++) {
  ...
}
Mr. Matt
A: 

foreach is faster than while(list()=each()) when you're not modifying values, if you're modifying the hash, while(list()=each()) is faster

Marc Gear
A: 

Use late-binding, that is only including specific files/classes when they are needed. Less code to parse.

DreamWerx
+6  A: 

I realise this doesn't answer the question - but I happen to think its worth saying.

Nearly all of these 'optimizations' are premature, and should probably not be implemented at the expense of making code easy to understand and maintain. There are likley to me much larger bottlenecks than these optimizations.

Marc Gear
Of course. I'm working on a quite mature project which needs a bit of tweaking in the speed department.
Jrgns
If you're working on a mature product, then this isn't the sort of otimisation you should really be making. Profile your code, and see where the biggest wins are, add a data caching strategy, and an opcode cache as well as profiling the use of your external dependancies (db etc).
Marc Gear
Those sorts of things will give you much better scope for improvement, as well as being easier to do than refactor all your code to do things like ommiting double quotes.
Marc Gear
+7  A: 

If this is for a static environment, such as a web server module or using FastCGI, use an opcode cache. That way, each file is only compiled once (or whenever it is updated on disk). APC is a popular open source opcode cache and is scheduled to be included in PHP6.

R. Bemrose
Exactly, we saw a 30% increase in performance when using APC.
Ryan Doherty
+4  A: 

If you really need to optimise "the PHP" code then using a "PHP accelerator" is probably the best bang for your buck - it basically just caches the compiled bytecode of scripts so this operation doesn't have to be done repeatedly. Useful for OOP with lots of different files, etc.

David McLaughlin
+1  A: 

Reduce the number of operations within loops whenever possible.

Here's a pointless-but-illustrative example.

<?php
$data = array(
     'Santa Claus'
    , 'Clark Kent'
    , 'Barack Obama'
);

$displayAsUpperCase = true;

foreach ( $data as $datum )
{
    if ( $displayAsUpperCase )
    {
     echo strtoupper( $datum ), "\n";
    } else {
     echo $datum, "\n";
    }
}

See how the condition is executed every iteration? This is unnecessary, since the $displayAsUpperCase flag never changes during the lifetime of the loop. The solution is to use the value of the flag to define a callback

<?php
$data = array(
     'Santa Claus'
    , 'Clark Kent'
    , 'Barack Obama'
);

$displayAsUpperCase = true;

$displayCallback = ( $displayAsUpperCase ) ? 'strtoupper' : create_function( '$data', 'return $data;' );

foreach ( $data as $datum )
{
    echo call_user_func( $displayCallback, $datum ), "\n";
}

For those of you taking notes, this is a similar strategical process to polymorphism.

Peter Bailey
You are probably slowing the script by having double the function calls. Try $displayCallback($datum);
orlandu63
A: 

use the string handling functions instead of preg_ and ereg_ functions if you can.

Marc Gear
+18  A: 

Performance is sooooo overrated. Lots of programmers tend to overoptimise their code for speed forgetting that in most cases they:

  1. Make the program more obscure
  2. Introduce potential flaws
  3. Increase codebase that needs to be maintained

All these factors significantly raise the overall development cost. Why not focus on lowering cost instead of chasing another 10µs optimisation? What is the single biggest share in software development cost? Is it server? Network throughput? CPU cycles? RAM or disk space? Nope. It's the programmer. You cost big bucks!

Write your programs so they are optimised for humans, not computers. It is much faster for you to create a Decorator and waste some CPU power than trying to inject if-conditions to whole inheritance tree and then wasting another hour scratching your head what the hell went wrong.

Computers should work hard. For you it is better to work smart.

Michał Rudnicki
Excellent point. Should be noted, though, that while the "over-rated" label applies to programmers developing initial architecture/code, what about programmers tasked with optimizing expensive components of a code base, perhaps w/ a mandate to trade off readability for performance where reasonable.
micahwittman
Measure, and see what's slow @micahwittman, then you optimise that. Most of the time, it will be a database access.
Alister Bulman
totally agree, optimize database queries isntead of pure PHP code, since they eat a LOT of resources (CPU, IO, MEM)
Jauzsika
+4  A: 

There are several ways to improve performance including:

  • Use a php accelerator.
  • Make use of Caching.
  • Best of all, use a profiler to actually pin-point your performance issues. Nothing is worse then to solve problems that aren't there.

I would advice reading http://developer.yahoo.com/performance/rules.html not php specific but very usefull.

Johnny
+1 for using a profiler. Don't waste your time optimising things that aren't slowing you down.
Brendan Long
+3  A: 

Use an opcode cache: http://php.net/apc

Armin Ronacher
A: 

Opcode cache's such as eAccelerator I've always found have made a significant improvement to the performance of many applications.

Adam Gibbins
+2  A: 

To sum things up...

  1. Don't worry about optimization until you actually run into a bottleneck. Premature optimization will just introduce bugs and make the code harder to maintain.
  2. Use a PHP Opcache such as APC, xCache or Turck MMCache, or a memory caching system such as memcached.

The following is a list of "optimizations" you can use in your code, but the differences are so minuscule, you shouldn't use these at the expense of unreadable, unmanageable code.

  1. Use require and include instead of require_once and include_once, which are slower.
  2. echo is faster than print
  3. $_SERVER['REQUEST_TIME'] is faster than time(), which invokes a system call (php5)
  4. Calculate the limit for a for loop before the loop, not in the loop condition.
  5. Only inlcuded code/files/classes that are actually needed.
  6. Enclose literal strings in single quotes unless they actually contain variables you want to evaluate and insert into the string.
  7. Type-specific comparison operators are faster then non-type specific ones, when you know the types of the variables you are comparing. $x === 5 is faster than $x == 5, but will evaluate to false if $x is the string '5' for example.
  8. Use string functions instead of regular expressions where appropriate. To find if a string is contained in another string use strpos or stripos. To replace values in a string when you don't need regular expressions, use str_replace.
  9. preg_* functions are faster than ereg_* regular expression functions.
  10. Do as little as possible inside loops, especially avoid many if constructs when possible.
  11. Free memory with unset, when a variable is no longer needed.
  12. Using full paths for includes and requires is faster than relative paths.
  13. Avoid "magic" functions when possible. __autoload, __call etc.
  14. Sending multiple parameters to echo (separated by a comma) is faster than string concatenation.

You also have to correctly optimize your database schema and queries.

  1. Make sure you denormalize your database in key areas where appropriate.
  2. Make sure you have indices where needed.
  3. Make sure you don't have unneeded indices.
  4. Optimize your queries. For example an IN() sub-query is many,many times slower than an INNER JOIN sub-query.
David
A: 

Basic optimalisation philosophy is: Having to do less, but with the same end result.

Havin said that, performance issues are almost always I/O bound (SQL, etc), So focus on that, instead of optimizing for CPU and memory.

If speed is important you should consider building a profiler in your scripts This profiler can be used to see which pages / queries are slow. Basic example of a profiler:

... in query function ....
global $query_log;
$start = microtime(true);
mysql_query($sql);
$query_execution_time = microtime(true) - $start;
$query_log[$sql] = query_execution_time;

... end of script ....
var_dump($query_log);

If your php system is using classes I can recommend looking into the "__autoload" / "spl_autoload_register" function. This mechanism can reduce your code. (less include/require lines) and speed up your code because class files will only be loaded when they are used.

Bob Fanger
A: 

If you want a side-by-side comparison of different PHP language features, check out PHP Benchmark. It actually runs comparison tests each time the page is loaded. If you search, there are other sites like it as well.

VirtuosiMedia
+2  A: 

Some of the above tips look very similar to what Google has published some time ago:

Google Optimization Tips

A lot of the advice (like echo vs print, single vs double quotes, etc.) have been actually contradicted by the PHP team themselves:

PHP optimization advice clarified

and here is another article with some numbers:

Debunking Google’s Internet Optimization Tips

YiSh
+4  A: 

You really need to check this site out : The PHP Benchmark.

The code examples on the site are automatically generated and run when you enter the site and the benchmark is added to the global statistics.

Really cool.

Jonathan