What are some good PHP performance tips?
I've heard of some performance tips for PHP such as using strtr()
over str_replace()
over preg_replace()
depending on the situation.
As far as using certain functions over others, and code style, what are some of the performance tips that you know of?
Edit: I'm not talking abo开发者_StackOverflow中文版ut use of things that make code less readable, like !isset($foo{5})
over strlen($foo) < 5
, I'm talking about things like using preg_ functions over ereg_ functions for regex.
Edit: The reason I ask this is not for nitpicking over when to optimize, but to get a general idea of what tends to be most efficient in a limited set of alternatives. For instance, checking if a mysql statement returned an error is arguably better practice than suppressing the errors to begin with.
This question is really vague. When you want to optimize your script, you first check your database and try to optimize your algorithms. There aren't many pure PHP performance tips that are going to matter. Let's see :
Concatening variables is faster than just putting them in a double-quotation mark string.
$var = 'Hello ' . $world; // is faster than $var = "Hello $world"; // or $var = "Hello {$world}";
Yes, it's faster, but the second and third form are even more readable and the loss of speed is so low it doesn't even matter.
When using a loop, if your condition uses a constant, put it before the loop. For instance :
for ($i = 0; $i < count($my_array); $i++)
This will evaluate count($my_array) every time. Just make an extra variable before the loop, or even inside :
for ($i = 0, $count = count($my_array); $i < $count; $i++)
The worst thing is definitely queries inside loops. Either because of lack of knowledge (trying to simulate a JOIN in PHP) or just because you don't think about it (many insert into in a loop for instance).
$query = mysql_query("SELECT id FROM your_table"); while ($row = mysql_fetch_assoc($query)) { $query2 = mysql_query("SELECT * FROM your_other_table WHERE id = {$row['id']}"); // etc }
Never do this. That's a simple INNER JOIN.
There are probably more, but really, it's not worth writing all of them down. Write your code, optimize later.
P.S. I started writing this answer when there was none, there may be some things already said in links.
Edit: for some reason, I can't format the code correctly. I really don't understand why.
PREMATURE OPTIMIZATION IS THE ROOT OF ALL EVIL
And that's the most important tip you need. If some day you have a real performance problem, profile your application, detect the compromised areas, and came here to ask again :)
66 Tips for optimizing your PHP
Here are Webber’s points:
- Use JSON Instead of XML.
- Can also use sprintf instead of variables contained in double quotes, it’s about 10x faster.
- Avoid the PHP mail() function header injection issue.
- If a method can be static, declare it static. Speed improvement is by a factor of 4.
- echo is faster than print.(* compare with list from phplens by John Lim)
- 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.
- Incrementing an undefined local variable is 9-10 times slower than a pre-initialized one.
- Just declaring a global variable without using it in a function also slows things down (by about the same amount as incrementing a local var). PHP probably does a check to see if the global exists.
- Method invocation appears to be independent of the number of methods defined in the class because I added 10 more methods to the test class (before and after the test method) with no change in performance.
- Methods in derived classes run faster than ones defined in the base class.
- A function call with one parameter and an empty function body takes about the same time as doing 7-8 $localvar++ operations. A similar method call is of course about 15 $localvar++ operations.
- Surrounding your string by ‘ instead of ” will make things interpret a little faster since php looks for variables inside “…” but not inside ‘…’. Of course you can only do this when you don’t need to have variables in the string.
- When echoing strings it’s faster to separate them by comma instead of dot. Note: This only works with echo, which is a function that can take several strings as arguments.
- A PHP script will be served at least 2-10 times slower than a static HTML page by Apache. Try to use more static HTML pages and fewer scripts.
- Your PHP scripts are recompiled every time unless the scripts are cached. Install a PHP caching product to typically increase performance by 25-100% by removing compile times.
- Cache as much as possible. Use memcached – memcached is a high-performance memory object caching system intended to speed up dynamic web applications by alleviating database load. OP code caches are useful so that your script does not have to be compiled on every request
- When working with strings and you need to check that the string is either of a certain length you’d understandably would want to use the strlen() function. This function is pretty quick since it’s operation does not perform any calculation but merely return the already known length of a string available in the zval structure (internal C struct used to store variables in PHP). However because strlen() is a function it is still somewhat slow because the function call requires several operations such as lowercase & hashtable lookup followed by the execution of said function. In some instance you can improve the speed of your code by using an isset() trick.
Ex. view sourceprint?1.if (strlen($foo) < 5) { echo "Foo is too short"; }vs.
view sourceprint?1.if (!isset($foo{5})) { echo "Foo is too short"; }Calling isset() happens to be faster then strlen() because unlike strlen(), isset() is a language construct and not a function meaning that it’s execution does not require function lookups and lowercase. This means you have virtually no overhead on top of the actual code that determines the string’s length.
- When incrementing or decrementing the value of the variable $i++ happens to be a tad slower then ++$i. This is something PHP specific and does not apply to other languages, so don’t go modifying your C or Java code thinking it’ll suddenly become faster, it won’t. ++$i happens to be faster in PHP because instead of 4 opcodes used for $i++ you only need 3. Post incrementation actually causes in the creation of a temporary var that is then incremented. While pre-incrementation increases the original value directly. This is one of the optimization that opcode optimized like Zend’s PHP optimizer. It is a still a good idea to keep in mind since not all opcode optimizers perform this optimization and there are plenty of ISPs and servers running without an opcode optimizer.
- Not everything has to be OOP, often it is too much overhead, each method and object call consumes a lot of memory.
- Do not implement every data structure as a class, arrays are useful, too
- Don’t split methods too much, think, which code you will really re-use
- You can always split the code of a method later, when needed
- Make use of the countless predefined functions
- If you have very time consuming functions in your code, consider writing them as C extensions
- Profile your code. A profiler shows you, which parts of your code consumes how many time. The Xdebug debugger already contains a profiler. Profiling shows you the bottlenecks in overview
- mod_gzip which is available as an Apache module compresses your data on the fly and can reduce the data to transfer up to 80%
- Excellent Article about optimizing php by John Lim
As Reihold Webber pointed to a post from John Lim (found this article copied without state the source here), then i investigate further and truly that is an excellent best practice tutorial for optimizing the php code performance, covered almost all aspects from low level webserver configuration, PHP configuration, coding styling, and performace comparisson as well.
Another good practice for better php performance as written in cluesheet.com are:
- Do use single quotes over double quotes.
- Do use switch over lots of if statements
- Do avoid testing loop conditionals with function tests every iteration eg. for($i=0;i<=count($x);$i++){…
- Do use foreach for looping collections/arrays. PHP4 items are byval, greater than PHP5 items are byref
- Do consider using the Singleton Method when creating complex PHP classes.
- Do use POST over GET for all values that will wind up in the database for TCP/IP packet performance reasons.
- Do use ctype_alnum,ctype_alpha and ctype_digit over regular expression to test form value types for performance reasons.
- Do use full file paths in production environment over basename/fileexists/open_basedir to avoid performance hits for the filesystem having to hunt through the file path. Once determined, serialize and/or cache path values in a $_SETTINGS array. $_SETTINGS["cwd"]=cwd(./);
- Do use require/include over require_once/include_once to ensure proper opcode caching.
- Do use tmpfile or tempnam for creating temp files/filenames
- Do use a proxy to access web services (XML or JSOM) on foreign domains using XMLHTTP to avoid cross-domain errors. eg. foo.com<–>XMLHTTP<–>bar.com
- Do use error_reporting (E_ALL); during debug.
- Do set Apache allowoverride to “none” to improve Apache performance in accessing files/directories.
- Do use a fast fileserver for serving static content (thttpd). static.mydomain.com, dynamic.mydomain.com
- Do serialize application settings like paths into an associative array and cache or serialize that array after first execution.
- Do use PHP output control buffering for page caching of heavilty accessed pages
- Do use PDO prepare over native db prepare for statements. mysql_attr_direct_query=>1
- Do NOT use SQL wildcard select. eg. SELECT *
- Do use database logic (queries, joins, views, procedures) over loopy PHP.
- Do use shortcut syntax for SQL insers if not using PDO parameters parameters. eg. INSERT INTO MYTABLE (FIELD1,FIELD2) VALUES ((“x”,”y”),(“p”,”q”));
Ref - gist.github.com
I visited other blogs and compared all the above points and tried to add everything here for optimising your PHP code.
Hope this helps you.
If you're looking for good tips on how to program your code so that it's the most efficient, refer to http://www.phpbench.com/. They show a lot of comparisons on various aspects of programming so you can utilize the best methods that fit your needs. Generally it comes down to whether you're looking to save on processing power or memory usage.
http://talks.php.net/show/digg/0 - A talk given by PHP themselves on performance
http://code.google.com/speed/articles/optimizing-php.html - Recommendations by Google on how to speed up your applications
Most commonly your problems aren't with PHP, but are going to be MySQL or http requests issues.
This one might seem a bit extreme but...
PHP is extremely slow. This is undeniable. It is one of the slowest languages out there. If you really want maximum performance I'm going to stay stop right here and use another language.
Chances are you don't need maximum performance as computers tend to be pretty powerful today and scaling or caching is an option. PHP also tends to become faster with new releases, especially PHP 7 so stating recent will likely give you free performance improvements. Differences between versions may make some micro optimizations pointless.
Completely contrary to the statement about PHP being the slowest language around, you may find that in some cases it beats nearly every interpreted language out there. This is because PHP originally was meant as a very simple a wrapper for C and many of your PHP functions wrap C functions which makes them quite fast. This actually tends to be the case with most interpreted languages but it is far more noticeable in PHP.
Contrary to that again some of in built functions may have performance issues where they try to do too much or aren't implemented well. I think until PHP 7 array_unique had been implemented in a very strange and excessively complex way where it would be quicker to use something such as array_flip and array_keys instead.
PHP is like that. It's one of the most outrageous languages out there as one with a collection of contradictory attributes that are extreme opposites. It's one of the most inconsistent yet the among the easiest to learn. PHP is one of the worst languages out there having grown organically more so than adhering to a design yet it it one of the most productive languages as a DSL for web development. PHP is very bad at scaling yet one of the most scalable web languages out there when run under Apache. I could go on but the point is to expect confusion when it comes to PHP.
Ditching PHP is not without a cost. Productivity in PHP tends to be much higher than in other languages for webdev and the bar for entry is very low.
If you want to have the best of both worlds then simply make your PHP code as simple as possible with the goal primarily of it working than it being fast. The next step after this is to make sure you keep good logs so that you can find the requests that have the highest latency or take the most resources. Once you know this you can to targeted profiling. Think of it like this, your logs will tell you what file or request to profile, your profiling will tell you which lines or blocks of code are slow.
Don't forget though that it's often not PHP that's slow or hard to scale but other resources your PHP scripts depend on such as database.
General resource monitoring is also useful. For example if your ambient CPU usage is less than 5% why do anything unless latency crops up somewhere? This also helps to give you more hints about where PHP is stalling (where the bottlenecks are, network, HDD IO, memory, CPU, etc). Also keep in mind that today hardware is really really cheap and throwing hardware at problems may turn out much more effective. Such monitoring again allows a targeted approach. I'm an oldie with experience of limited hardware and I can tell you back in the day I used to prematurely optimize a lot. This would give a good return but today it just does not. Typically I can spend a month optimizing something and for the same cost of manhours buy some hardware that might result in a two times performance increase without the big effort. I would not take this too far, hardware does not solve everything but look at it like this, no matter how much you try to optimize there are hard limits presented by hardware so if you go too far in trying to make it work with poor hardware you will quickly hit the realm of diminishing returns.
Once your find these problem areas you can then attempt to optimize them with better PHP or caching. In most cases this might be enough. Often you may find PHP is not the bottleneck but something else such as database access.
If you find that you cannot optimize in PHP or with caching you have to think of something else. Using another language is an option and of course here comes the possibility of using C and then wrapping it in PHP as an extension. C is expensive to write in general so this approach lets you use it only where you need it or rather where you receive the most benefit. This is called hotspot optimisation.
Outside of this there are many other alternatives and you need not wrap only C but if PHP can't do it, PHP can't do it. You can also consider scaling across multiple nodes or processes but keep in mind that in some cases PHP does not scale well when it comes to parallel processing due shared nothing (not many scaling loads need to share for a benefit).
Whatever you decide, when it comes down to it, we can give 1000 tips about micro-optimisation. Perhaps one of the best all round ones I can give you it to try to put as much into as few PHP native functions as possible because these will run bulk operations in C much faster. You should also follow good theoretical concepts when it comes to algorithm design about things such as time complexity because these are universally applicable. In fact, the majority of performance tips people can give you are probably going to be general programming concepts and not specific to PHP. I would also suggest avoiding library bloat or bulky frameworks. The more they promise the more likely it is to be too good to be true in the real world. Simplicity is key and while libraries are always good think first, are you including ten thousand lines of code to save you writing ten lines out of a hundred which you could turn into a function and reuse yourself.
Using Opcache or APC if using versions of PHP below 5.5 will instantly give a good speed improvement on PHP parse times and make this a non-concern. PHP 5.5 should have it built in but make sure it's enabled.
The topic of what is faster than what in what situation pits thousands of things against thousands of things so your best bet is to study and learn more about what PHP actually is, how it works, and how to measure, test and analyse performance. If you have a good sense of how PHP works under the hood you'll be able to better intuit problems when they do arise. Optimizing ten lines of code can become a 10000 word debate. Imagine your application when it has thousands of lines of code.
I do understand in a few cases the importance or benefit of pre-emptive and micro optimization (largely consists of avoiding performance quirks in languages where performance is disproportionately reduced). However in reality it is usually next to impossible to achieve the kind of gains you expect (again though I have to say the biggest impact you can have if you really care about performance is to ditch PHP altogether, basically this can be seen like asking how can I make a snail fast, the answer is if speed it so important use something built for that). Even the experienced and knowledgeable can have a hard time with this. Almost no one gets it right first time. So where you really want to spend efforts on is maintainability. Keep your code consistent, tidy and well organised. Used VCS to be able to easily delete things (don't comment out code or rename files to .old). Make sure you stay DRY and in general follow good practices. TIAS, Google, etc.
Usually pre-mature optimization is a veeeery bad idea. It really doesn't matter when you make your code run 0.5ms faster when single SQL query takes 80ms.
You should profile code and focus on bottle necks and then try things like caching (static, APC, Memcached). Microoptimizations are the very last step when you've got perfect application design and still need more performance from certain modules/functions.
Lets imagine you have an array of words.
Like this: $words=array('banana','cat','tuna','bicycle','kitten','caffeine');
And then you have a search term to find, like this: $find='ca';
And you want to know all the elements that start with that given term.
We would usually do like this:
foreach($words as &$word)if(preg_match('@^'.$find.'@',$word))echo $word,'<br>';
Or the fastest way:
foreach($words as &$word)if(strpos($find,$word)==0)echo $word,'<br>';
But why don't we just do like this:
foreach($words as &$word)if($find==($find&$word))echo $word,'<br>';
You shave off a few bytes AND it is faster 'cause you don't have to waste time calling functions.
This question (and the answers) are rather dated however it came up high in the listings when I googled for 'PHP performance'.
While jgmjgm makes some good points, the execution time of PHP is typically a tiny proportion of the time a user spends waiting for a page to appear, but explaining why, let alone detailing the remedies would take far too long here.
The first step is to identify the things which are taking the most time - and for a web based application you should start at the browser. Google Chrome has a good profiler and for Firefox, there is the Firebug extension. If the slow bit is PHP then dig further with a profiler such as xdebug, but remember that this will encompass any database and file IO.
Use single rather than double quotes wherever possible. (Or even a variable, as silly as it sounds) Abuse the PHP associative arrays, they are hash tables and are really fast for any kind of look up.
However, don't focus so much on low level performance. Tasks you perform in PHP are normally very simple. They are typically often repeated. What this means is the real focus you should have for speed are are around the edges of PHP.
Focus on speed between PHP and your Database. Focus on the size of markup on the way out. Focus on cache.
It is VERY rare that you'll see any kind of win out of optimization of the code itself. At least on the scale of picking one function over another. Clearly you want to avoid redundant or useless repetition. But aside from that you shouldn't really worry.
You must measure before you optimize. Without measurements, you cannot have goals. Without goals, you are wasting your time.
If you discover that your webpage takes 250ms to render, is that fast enough? If not, how fast should it be? It won't get down to zero. Do you need it to be 200ms?
Use a tool like XDebug (http://www.xdebug.org/) to determine where the hotspots in your code are. Chances are you will find that your app is taking 80% of its time accessing the database. If your app is taking 200ms to get data from the database, and .01ms in str_replace
calls, then the speedups of going to strtr
, or of using echo
instead of print
are so small as to be irrelevant.
The dream of being able to use strtr
instead of str_replace
and get noticeable, measurable speedups is a fantasy.
It's obvious, but creating objects is also costly, so for ex. if you need a timestamp doing a time() is double faster than doing a date_create()->getTimestamp.
for ($a=1;$a<1000000;$a++) {
$e = time(); // In my tests about 2x faster than:
//$e = date_create()->getTimestamp();
}
- Use Native PHP Functions
- Use Single Quotes
Using single quotes ( ‘ ‘ ) is faster than using double quotes( ” ” ) - Use = = =
Use “= = =” instead of “= =”, Calculate Only Once Calculate and assign the value to the variable if that value is getting used numerous time rather than calculating it again and again where it is being used.
For example, the following will degrade the performance.
for( $i=0; i< count($arrA); $i++){ echo count($arrA); }
The script below will perform much better.
$len = count($arrA); for( $i=0; i< $len; $i++){ echo $len;
}
Used Switch Cases
- Use JSON
Use JSON instead of XML while working with web services as there are native php function like json_encode( ) and json_decode( ) which are very fast. 7. Use isset Use isset( ) where ever possible instead of using count( ), strlen( ), sizeof( ) to check whether the value returned is greater than 0.
- Concatening variables is faster than just putting them in a double-quotation mark string.
- Please consider binding variables to database's statament instead of putting them into a SQL clause. The same method is similar for the Oracle RDBMS and the MySQL, maybe others too (parse, bind, execute).A query with bound variables is faster prepared for running them more than once.
- If you have more than one row to insert, you may use one bulk DML.
精彩评论