views:

321

answers:

11
+3  Q: 

PHP performance

What can I do to increase the performance/speed of my PHP scripts without installing software on my servers?

A: 

There is no magic solution, and attempting to provide generic solutions could well just be a waste of time.

Where are your bottlenecks? For example are your scripts processor/database/memory intensive?

Have you performed any profiling?

Andrew Grant
A: 

Whenever I look at performance problems, I think the best thing to do is time how long your pages take to run, and then look at the slowest ones. When you get these real metrics, you can often improve performance on the slowest ones by orders of magnitude, either by fixing a slow SQL query or perhaps tightening up the code a bit.

This of course requires no new hardware or special software, just a critical eye on the existing code.

That said, this will only work for so long... if you really are getting enough traffic to hit the limits of your hardware, and/or there is some code that is just inherently slow and really required, you will have to look at other possibilities.

Mike Stone
+7  A: 

Profile. Profile. Profile. I'm not sure if there is anything out there for PHP, but it should be simple to write a little tool to insert profiling information in your code. You will want to profile function times and SQL query times.

So where you have a function:

function foo($stuff) {
    ...
    return ...;
}

I would change it to:

function foo($stuff) {
    trace_push_fn('foo');
    ...
    trace_pop_fn('foo');
    return ...;
}

(This is one of those cases where multiple returns in a function become a hinderance.)

And SQL:

function bar($stuff) {
    trace_push_fn('bar');

    $query = ...;
    trace_push_sql($query);
    mysql_query($query);
    trace_pop_sql($query);

    trace_pop_fn('bar');
    return ...;
}

In the end, you can generate a full trace of the program execution and use all sorts of techniques to identify your bottlenecks.

Frank Krueger
A: 

I'm responsible for a large reporting system and we track the slowest reports kind of like that. I fire a unique key into the db when the report starts and then when it finishes I can determine how long it took. I'm using the database because that way I can detect when pages timeout (which happens a lot more than I'd like)

Eric Goodwin
+2  A: 

One reasonable technique that can easily be pulled off the shelf is caching. A vast amount of time tends to go into generating resources for clients that are common between requests (and even across clients); eliminating this runtime work can lead to dramatic speed increases. You can dump the generated resource (or resource fragment) into a file outside the web tree, and then read it back in when needed. Obviously, some profiling will be needed to ensure this is actually faster than regeneration - forcing the web server back to disk regularly can be detrimental, so the resource really does need to have heavy reuse.

You might also be surprised how much time is spent inside badly written database queries; time common generated queries and see if they can be rewritten. The amount of time spent executing actual PHP code is generally pretty limited, unless you're using some sub-optimal algorithms.

Neither of these are limited to PHP, though some of the PHP "magicy" approaches/functions can over-protect one from thinking about these concerns. For example, I recently updated a script that was using array_search to use a binary search over a sorted array, and gained the expected exponential speedup.

Adam Wright
A: 

Follow some of the other advice first like profiling and making good resource allocation decisions, e.g. caching.

Also, take into account the performance of outside resources like your database. In MySQL you can check the slow query log for example. In addition make sure you didn't design your database an forget about it. Optimizing your queries (again for MySQL) against real data can pay of big.

Barrett Conrad
A: 

@all
Assuming that we remove SQL queries, flat file access, remote file access. What things should be avoided in the scripts themselves to improve performance, if anything.

Unkwntech
A: 

The ones I can think of...

  • Loop invariants are always a good one to watch.

  • Write ESTRICT and ENOTICE compliant code, particularly if you are logging errors.

  • Avoid the @ operator.

  • Absolute paths for requires and includes.

  • Use strpos, str_replace etc. instead of regular expressions whenever possible.

Then there's a bunch of other methods that might work, but probably wont give you much benefit.

Dave Marshall
+2  A: 

Really consider using XDebug profiler: it helps with checking how much a certain function is being executed against what you would have expected.

I try to decrease instructions while improving code readability by replacing logic with array-lookups when appropriate. It's what Jeff Atwood wrote in [The Best Code is No Code At All][1].

  • Also, avoid loops inside another loop, and nested if/else statements.
  • Short functions. Sometimes a lot of code does not need to be executed when the result-value is already known.
  • Unnecessary testing:

    if (count($array) === 0) return;

    can also be written as:

    if (! $array) return;

    Another function-call eliminated!

    [1]: http://www.codinghorror.com/blog/archives/000878.html"The Best Code is No Code At All"

Wimmer
+1  A: 

including files is slow, and requiring them is even slower. If you use __autoload for including every class then that will add up. for example.

I'm always a bit wary of trying to be too clever in terms of code optimisation, if it sacrifices code clairty. If you need to make code obscure to make it fast, would it not be cheaper to upgrade hardwear instead of wasting your time trying to tweak code? Processor cycles are cheaper than programmer cycles, after all.

A: 

Rasmus Lerdorf gave some good tips in his recent presentation "Simple is Hard" at FrOSCon '08. If you are using a bytecode cache (and you really should be using one), include path misses hurt a lot, so optimize your require/require_once.

TobiX