Optimization of programs on PHP
Bear{Take out} $peremennye from " text lines " - acceleration of 25-40 %
One and tazhe operation of giving (or echo/print for a conclusion to the screen) depending on, whether variables in kavycheki are made whether or not, strongly influences speed. In the first and second variants blanks, that vyravnjat` the size of the general{common} code for parsing are added.
1. {$x = "test." $test;}
2. {$x = " test $test ";}
3. {$x = "test"; $x. = $ test;}
The variable $test contains a line "1234567890".
The counter kol-in
Calls the general{common}
vpemja spednee
vpemja % from min % from max
test N1 13.59113.591100.0 % of 70.9 %
test N2 15.06165.061640.9 % of 100.0 %
test N3 14.98704.987038.9 % of 98.5 %
So, never write $a = " $ b ", for it will brake the program (this line) on 40 %.
However, if at you the big line where it is a lot of the text and variables, distinction in speed decrease, since the general{common} expenses for parsing become much more, than different commands on efficiency. But why and to not increase speed of the program (lines of giving) almost by a quarter such simple method?
1. {$x = "test." $test. "test." $test. "test." $test;}
2. {$x = " test $test test $test test $test ";}
3. {$x = "test"; $x. = $ test; $x = "test"; $x. = $ test; $x = "test"; $x. = $ test;}
The counter kol-in
Calls the general{common}
vpemja spednee
vpemja % from min % from max
test N1 17.68947.689400.0 % of 66.0 %
test N2 19.55159.551524.2 % of 82.0 %
test N3 111.650611.650651.5 % of 100.0 %
Short variables no more than 7 symbols - acceleration of 15 %
How the length of names of variables influences speed of the program? If to use very long variables - it is obvious, that is rather strong. However and with short imenemi not all is simple:
1. {$x=1;}
2. {$x2=1;}
3. {$x03=1;}
4. {$x004=1;}
5. {$x0005=1;}
6. {$x00006=1;}
7. {$x000007=1;}
8. {$x0000008=1;}
9. {$x000000010=1;}
10. {$x00000000012=1;}
11. {$x0000000000014=1;}
12. {$x000000000000016=1;}
13. {$x0000000000000000000000000000032=1;}
Gives out predicted result:
The counter kol-in
Calls the general{common}
vpemja spednee
vpemja % from min % from max
test N1 11.70001.700000.0 % of 68.5 %
test N2 11.70281.702800.2 % of 68.6 %
test N3 11.71821.718201.1 % of 69.2 %
test N4 11.72281.722801.3 % of 69.4 %
test N5 11.75361.753603.2 % of 70.6 %
test N6 11.75041.750403.0 % of 70.5 %
test N7 11.77991.779904.7 % of 71.7 %
test N8 11.96041.960415.3 % of 78.9 %
test N9 11.98651.986516.9 % of 80.0 %
test N10 12.01192.011918.3 % of 81.0 %
test N11 12.03022.030219.4 % of 81.7 %
test N12 12.12882.128825.2 % of 85.7 %
test N13 12.48352.483546.1 % of 100.0 %
Variables from 32 symbols can tormoznut` the program almost on half.
But if to fill blanks (" "), that all the line long " $x=1;... " On length borrowed{occupied} one and too distance it turns out that:
1. {$x=1;}
2. {$x2=1;}
3. {$x03=1;}
4. {$x004=1;}
5. {$x0005=1;}
6. {$x00006=1;}
7. {$x000007=1;}
8. {$x0000008=1;}
9. {$x000000010=1;}
10. {$x00000000012=1;}
11. {$x0000000000014=1;}
12. {$x000000000000016=1;}
13. {$x0000000000000000000000000000032=1;}
The counter kol-in
Calls the general{common}
vpemja spednee
vpemja % from min % from max
test N1 12.11672.116701.9 % of 83.3 %
test N2 12.07662.076600.0 % of 81.7 %
test N3 12.09372.093700.8 % of 82.4 %
test N4 12.08212.082100.3 % of 81.9 %
test N5 12.11452.114501.8 % of 83.2 %
test N6 12.09212.092100.7 % of 82.3 %
test N7 12.10762.107601.5 % of 82.9 %
test N8 12.30582.305811.0 % of 90.7 %
test N9 12.30462.304611.0 % of 90.7 %
test N10 12.31072.310711.3 % of 90.9 %
test N11 12.31112.311111.3 % of 90.9 %
test N12 12.36802.368014.0 % of 93.2 %
test N13 12.54182.541822.4 % of 100.0 %
How to make comments on the test of a variable from one symbol (on 2 % medlenne the fastest) - I do not know... Likely, tests have the big error. I suggest somebody to start the test for hour (source codes of the test in the bottom of page).
One is clear - at length of variables in 8 and more symbols there is a sharp decline of productivity, up to 15 %! And the commands including the names of variables, it is a lot of. One more less sharp of horse racings on variables with a name of 16 symbols at length and more. And in other cases - the more, the longer, rather linear dependence.
Conclusion - do not use peremenny from 8 and more symbols, will win 15 % of speed (more correctly, will save).
Whether files in PHP brake? More correctly, how. Acceleration of 40 %.
Here do not brake. I somewhere read, ostensibly associative files in PHP terribly brake. Certainly, the test idle time, but the big difference between continuous simple (1), simple (2) and associative (3) files no (an element 0000 will be transformed in 0 - the same number, instead of a line). And " associative not continuous files " obviously brake.
1. {$test [0000] =1; $test [0001] =1; $test [0002] =1; $test [0003] =1; $test [0004] =1;}
2. {$test [1000] =1; $test [1001] =1; $test [1002] =1; $test [1003] =1; $test [1004] =1;}
3. {$test ["aa"] =1; $test ["bb"] =1; $test ["cc"] =1; $test ["dd"] =1; $test ["ee"] =1;}
4. {$test [aa] =1; $test [bb] =1; $test [cc] =1; $test [dd] =1; $test [ee] =1;}
5. {$test [0 [0] =1; $test [0 [1] =1; $test [0 [2] =1; $test [0 [3] =1; $test [0 [4] =1;}
6. {$test [2 [1] =1; $test [3 [8] =1; $test [4 [9] =1; $test [33 [99] =1; $test [123 [99] =1;}
7. {$test [a] [b] =1; $test [x] [y] =1; $test [d] [c] =1; $test [a] [s] =1; $test [b] [n] =1;}
The counter kol-in
Calls the general{common}
vpemja spednee
vpemja % from min % from max
test N1 15.39245.392401.1 % of 28.0 %
test N2 15.33325.333200.0 % of 27.7 %
test N3 15.76515.765108.1 % of 29.9 %
test N4 17.65437.654343.5 % of 39.7 %
test N5 16.66496.664925.0 % of 34.6 %
test N6 16.62216.622124.2 % of 34.3 %
test N7 119.282019.2820261.5 % of 100.0 %
That here it is possible to make comments.. All is obvious. Access to an element of an one-dimensional associative file by name, not quoted, brakes process on third (concerning the same example, but so-called). And in a two-dimensional file the program works medlenne already in 2.5 times! After such test you want you do not want, and in any program you will offer convenience - the reference{manipulation} to elements of a file by name without inverted commas.
Bear{Take out} multivariate files from " text lines " - acceleration of 25-30 %.
One-dimensional it is possible to not bear{not take out}.
At use of multivariate files in lines appreciable decrease{reduction} in speed Because of multidimensionality is observed is necessary to conclude variable in pair braces.
1. {$x = "test." $myarray ["name"] ["second"] [1.] "test";}
2. {$x = " test {$myarray [name] [second] [1]} test ";}
3. {$x = "test"; $x. = $ myarray ["name"] ["second"] [1]; $x = "test";}
The counter kol-in
Calls the general{common}
vpemja spednee
vpemja % from min % from max
test N1 13.53693.536900.0 % of 69.9 %
test N2 15.06055.060543.1 % of 100.0 %
test N3 14.60174.601730.1 % of 90.9 %
The same example with an associative 3 measured file, but with the reference{manipulation} to an element under his{its} index number{room}:
1. {$x = "test." $myarray [3 [2] [0]. "test";}
2. {$x = " test {$myarray [3 [2] [0]} test ";}
3. {$x = "test"; $x. = $ myarray [3 [2] [0]; $x = "test";}
The counter kol-in
Calls the general{common}
vpemja spednee
vpemja % from min % from max
test N1 13.30123.301200.0 % of 73.1 %
test N2 14.16674.166726.2 % of 92.3 %
test N3 14.51454.514536.8 % of 100.0 %
The difference in 1 and 2 variants is very small. It speaks, that losses on not an effective utilization of inverted commas not too big, than access to files (see tests in the first chapter{head}).
1. {$x = "test." $myarray ["test"] ". test ";}
2. {$x = " test$myarray [test] test ";}
3. {$x = " test {$myarray [test]} test ";}
The counter kol-in
Calls the general{common}
vpemja spednee
vpemja % from min % from max
test N1 12.84952.849500.0 % of 80.9 %
test N2 12.95192.951903.6 % of 83.9 %
test N3 13.52023.520223.5 % of 100.0 %
And now, on the basis of all three tests, a unequivocal conclusion: to use braces for a designation of borders of a name of an element of a multivariate file it is IMPOSSIBLE. It strongly reduces speed of job - 25-30 % (in the third variant from simple addition of brackets speed has gone down on a quarter). To not use a bracket it is impossible. Hence, a unique way to not lose 30 % of speed - to bear{take out} multivariate files from brackets.
The same test, but for one-dimensional:
1. {$x = "test." $myarray ["test"] ". test ". $myarray ["test"]. "test." $myarray ["test"];}
2. {$x = " test$myarray [test] testtest$myarray [test] testtest$myarray [test] test ";}
3. {$x = " test {$myarray [test]} testtest {$myarray [test]} testtest {$myarray [test]} test ";}
The counter kol-in
Calls the general{common}
vpemja spednee
vpemja % from min % from max
test N1 16.58436.584300.0 % of 78.0 %
test N2 16.77706.777002.9 % of 80.3 %
test N3 18.44068.440628.2 % of 100.0 %
Comparing last two tests obviously, that one-dimensional files can and be not born{be not taken out}, losses of only 3-4 % (and on simple variables - losses of 25-40 %!).
Regular expressions: PHP (POSIX) vs Perl.
PHP supports regular expressions of standard POSIX/eger*/and PERL/preg*/-guided (about their distinction here - php.spb.ru/regular_expression.html). Who from them works faster?
I want to warn beforehand fans{amateurs} of Pearl that were not pleased: though pearl-barley regi and more abruptly pkhpyshnykh, only and nobody prevents to use anything in PHP pearl-barley regi! Likely, therefore they were built also in PHP, what with a bit too brakes big...:-)
So, the elementary text. Search of simple expression in the text which will consist of repeated recurrence of given clause{article} (turns out the size of a variable $text in 3 Mb).
The test causes only 1 time for regi have the built - in means for keshirovanija results of compilation. I.e. before start proikhodit compilations, and repeated regi are not compiled. These are features of regular expressions. Different programming languages in a status to store{keep} different number otkompilirovannykh expressions that were caused (by way of a call in the program). And in the given test just there is no effect from compilation since function is caused only once.
1. {eregi ("MaS+iV", $text);}
2. {preg_match ("/MaS+iV/im", $text);}
The counter kol-in
Calls the general{common}
vpemja spednee
vpemja % from min % from max
test N1 11.33391.3339107.8 % of 100.0 %
test N2 10.64170.641700.0 % of 48.1 %
1. {eregi (" (ma [a-za-n] {1,20}) ", $text);}
2. {preg_match (" / (ma [a-za-n] {1,20})/im ", $text);}
The counter kol-in
Calls the general{common}
vpemja spednee
vpemja % from min % from max
test N1 10.45210.452176.9 % of 100.0 %
test N2 10.25560.255600.0 % of 56.5 %
Example for other expression and 30-megabajtnogo the text (all same repetitions of clause{article}, that you now read):
1. {eregi (" (ma [a-za-n] {1,20}) ", $text);}
2. {preg_match (" / (ma [a-za-n] {1,20})/im ", $text);}
The counter kol-in
Calls the general{common}
vpemja spednee
vpemja % from min % from max
test N1 11.34301.343060.6 % of 100.0 %
test N2 10.83650.836500.0 % of 62.3 %
I still wrote pieces five different expressions, but the tendency does not vary. Speed can vary, but Pelr overtakes POSIX a minimum on half. It is enough of it to bury functions of regular expressions from PHP (POSIX). For all functions is similar Perl-guided (all of them are built - in in PHP).
Further one very indicative example on same clause{article} (increase up to 28Mb). The example searches in the text e-mail. On property of "greed" of regular expressions the biggest will be found and nabolee the address close to a left edge.
This example will afflict fans{amateurs} of a pearl. It is pleasant to afflict them:-)
1. {eregi (" ([a-z_-] + ([a-z] [a-z-]*.) + ([a-z] {2} |com|mil|org|net|gov|edu|arpa|info|biz)) ", $text);}
2. {preg_match (" / ([a-z_-] + ([a-z] [a-z-]*.) + ([a-z] {2} |com|mil|org|net|gov|edu|arpa|info|biz))/im ", $text);}
The counter kol-in
Calls the general{common}
vpemja spednee
vpemja % from min % from max
test N1 111.682811.6828680.3 % of 100.0 %
test N2 11.49731.497300.0 % of 12.8 %
From one test to judge difficultly, but, probably, the more difficultly regular expression, the more POSIX lags behind from Perl.
And now the same example, but only in clause{article} (increase up to 28Mb) no ANY symbol (I have specially made a copy of clause{article} and has erased these symbols):
1. {eregi (" ([a-z_-] + ([a-z] [a-z-]*.) + ([a-z] {2} |com|mil|org|net|gov|edu|arpa|info|biz)) ", $text, $ok); echo $ok [1];}
2. {preg_match (" / ([a-z_-] + ([a-z] [a-z-]*.) + ([a-z] {2} |com|mil|org|net|gov|edu|arpa|info|biz))/im ", $text, $ok); echo $ok [1];}
The counter kol-in
Calls the general{common}
vpemja spednee
vpemja % from min % from max
test N1 10.58540.585400.0 % of 10.2 %
test N2 15.76715.7671885.2 % of 100.0 %
What do we see?.. Anything in this world not completely. Certainly, it very not optimized expression for search email'ov, but nevertheless all those who shouted to me in a forum " ereg - a sediment ", on it and similar examples can have a rest. It happens, that in the text there is no sobachki:-)
So, the conclusion about speed with examples has been given above. A conclusion unequivocal - it is necessary to use Perl-guided regular expressions. In nachele the chapter{head} I mentioned about keshirovanii otkompilirovannykh copies regov. If in the program one and too expression meets repeatedly, productivity can differ not simply repeatedly, and in 10-100-1000 times!
Seldujuhhij the example is caused 200 times successively above the text in 250Kb:
1. {eregi ("MaS+iV", $text);}
2. {preg_match ("/MaS+iV/im", $text);}
The counter kol-in
Calls the general{common}
vpemja spednee
vpemja % from min % from max
test N1 117.638417.638472381.4 % of 100.0 %
test N2 10.02430.024300.0 % of 00.1 %
What is kesh - know all. Probably with keshem in PHP problemmy... By the way, for the sake of an example, disconnect in BIOSe yours kompt`jutera kesh the processor and try to load Windows 2000... will not wait! (It seems, them name L1 and L2 - two different kesha for a code and the data of the first and second level what from them can be disconnected that.)
Cycles: for, foreach, while, count/sizeof () - acceleration of 15%-30 %
In the beginning of the program the file $test from integers (100000 elements) is created. Then the examples resulted below are once started. The cycle passes the given file 3-mja in the ways (different cycles) and carries out some operations. To not carry out in a cycle anything it is impossible, for it will be already completely not real test.
1. {$x=0; foreach ($test as $n) {$x=sprintf ("test%08i", $i);}}
2. {$x=0; for ($it=0; $it <100000; $it ++) {$x=sprintf ("test%08i", $i);}}
3. {$x=0; $it=0; while ($it <100000) {$x=sprintf ("test%08i", $i); $it ++;}}
4. {$x=0; for ($it=0; $it <count ($test); $it ++) {$x=sprintf ("test%08i", $i);}}
5. {$x=0; $it=0; while ($it <count ($test)) {$x=sprintf ("test%08i", $i); $it ++;}}
6. {$x=0; $co=count ($test); for ($it=0; $it <$co; $it ++) {$x=sprintf ("test%08i", $i);}}
7. {$x=0; $co=count ($test); $it=0; while ($it <$co) {$x=sprintf ("test%08i", $i); $it ++;}}
The counter kol-in
Calls the general{common}
vpemja spednee
vpemja % from min % from max
test N1 112.031312.0313154.4 % of 100.0 %
test N2 14.72904.729000.0 % of 39.3 %
test N3 14.77124.771200.9 % of 39.7 %
test N4 110.284710.2847117.5 % of 85.5 %
test N5 110.346610.3466118.8 % of 86.0 %
test N6 19.12719.127193.0 % of 75.9 %
test N7 19.14099.140993.3 % of 76.0 %
Why sprintf, instead of real echo? echo to use it is impossible, since from him{it} will be nemerjannyj the buffer (OUTPUT in a browser or the console).
Now about business. The indisputable conclusion - use foreach strongly brakes business, and between for and while the big difference no. (On the naked test for/while/foreach {..} brakes foreach - 30 %). It is not surprising, since foreach does{makes} a copy of a file, on what to be spent a lot of time (though it only hearings).
The conclusion with count () is not so obvious, because from the different text in a cycle of % tormoznutosti from the fastest variant sharply grows... I have taken a cycle with small loading - pass on a huge file $test + formatting by function sprintf. As you can see, varinty with count () and replacing this function peremnnoj $co differ on 10 % on speed among themselves (do not look on varinant with a constant in 100000, beforehand to know kol-in elements it is impossible).
Conclusion about not associative files: 1) foreach essentially slows down job 2) use count () in simple cycles - zamedlenenie 10 %. But on complex{difficult} cycles of loss from superfluous start count () will be absolutely imperceptible, so the situation is not obvious.
Comparison count () and sizeof ().
By a manual is aliasy. About it it is written on pages of functions and additional page " Appendex => Aliases list ". That we see on a file in 100000 elements:
1. {$x=0; for ($it=0; $it <count ($test); $it ++) {$x=sprintf ("test%08i", $test [$it]);}}
2. {$x=0; for ($it=0; $it <sizeof ($test); $it ++) {$x=sprintf ("test%08i", $test [$it]);}}
The counter kol-in
Calls the general{common}
vpemja spednee
vpemja % from min % from max
test N1 13.00873.008715.7 % of 100.0 %
test N2 12.59982.599800.0 % of 86.4 %
Let tests will have errors... But the result one - count () appreciablly lags behind on speed from sizeof ()! KHm, I to recording in a manual would make a postscript: " The sizeof () function is an alias for count (), but last strongly brakes! "
If kol-in elements in a file it is less 65000 (64K) these functions on speed practically are not distinct. Here a conclusion idle time - we pass to use sizeof (), as accelerated aliasa count (). It will bring the results on huge files.
Associative files: testing of different ways perebora
With them the problem is observed tazhe: on different files on size different functions are effective, but it is the bettest foreach!
File in 200 elements and 1000 repetitions of the program:
1. {$x=0; foreach ($test as $k => $ v) {$x=sprintf (" %s => % sn ", $k, $v);}}
2. {$x=0; reset ($test); while (list ($k, $v) = each ($test)) {$x=sprintf (" %s => % sn ", $k, $v);}}
3. {$x=0; $k=array_keys ($test); $co=sizeof ($k); for ($it=0; $it <$co; $it ++) {$x=sprintf (" %s => % sn ", $k [$it], $test [$k [$it]]);}}
4. {$x=0; reset ($test); while ($k=key ($test)) {$x=sprintf (" %s => % sn ", $k, current ($test)); next ($test);}}
The counter kol-in
Calls the general{common}
vpemja spednee
vpemja % from min % from max
test N1 18.12228.122200.0 % of 78.7 %
test N2 110.322110.322127.1 % of 100.0 %
test N3 19.79219.792120.6 % of 94.9 %
test N4 18.97118.971110.5 % of 86.9 %
Too most, but a file in 5000 elements and 200 repetitions:
The counter kol-in
Calls the general{common}
vpemja spednee
vpemja % from min % from max
test N1 114.447314.447300.0 % of 67.2 %
test N2 118.680118.680129.3 % of 86.9 %
test N3 121.505621.505648.9 % of 100.0 %
test N4 115.851415.851409.7 % of 73.7 %
Again too most, but a file in 100000 elements and without repetitions:
The counter kol-in
Calls the general{common}
vpemja spednee
vpemja % from min % from max
test N1 13.51163.511600.0 % of 82.8 %
test N2 13.97243.972413.1 % of 93.6 %
test N3 14.24364.243620.8 % of 100.0 %
test N4 14.00264.002614.0 % of 94.3 %
Other tests for single cycles too show advantage foreach.
The resume:
* sizeof () it is better, than count ()
* In cycles sizeof it is better to replace with a variable in general
* for and while practically not otlichimy
* For perebora simple index files it is necessary to use for or while
* For perebora associative files it is necessary ispol`zot`va foreach
For reading a file file () is faster, than fopen+cikl - acceleration of 40 %
To read in a file $x a file in the size 1Mb (100000 lines on 10 bytes) are possible to use two variants: reading of a file with the help file (), or a traditional method fopen/fgets. Certainly, for files of different volume and contents speed can vary. But in the given example the statistics is those: file("1Mb_file.txt ") works on 40 % faster, than:
$f=fopen ("1Mb_file.txt", "r") or die (1);
while ($x [] =fgets ($f, 1000));
fclose ($f);
Similar variants
$f=fopen ("1Mb_file.txt", "r") or die (1);
while ($s=fgets ($f, 1000)) $x [] = $s;
fclose ($f);
Or
$f=fopen ("1Mb_file.txt", "r") or die (1);
while (! feof ($f))) $x [] =fgets ($f, 1000);
fclose ($f);
Work even more slowly (in the second case superfluous function feof () appreciablly reduces speed). The same test, but on 15Mb a file (100000 lines on 150 bytes) shows a difference in 50 %, for the benefit of file (). The test was spent so that to exclude background svopping in an operating time because of previous commands of creation / reading of such big files. To count up too most on very small files in 1-2 KB it is not obviously possible, since operation of reading cannot be repeated during one test, operations of reading will be keshirovat`sja...

|