* Няколко съвета за по-бързи програми на PHP
Публикувано на 22 март 2010 в раздел ОСУП.
Тази статия определено не е свързана със "сигурно програмиране", но реших, че може все пак да влезне в употреба. През годините съм слушал много съвети за това как да се оптимизира код така, че да отнема минимални ресурси. Естествено основната тежест в такава задача пада върху алгоритмите. Има обаче и други, по-дребни "трикчета", които отнемат някоя друга милисекунда от времето за изпълнение. Честно казано никога не съм бил привърженик на този род оптимизации, защото най-често правят кода нечетим. Въпреки това ще споделя някои неща, които съм запомнил през времето, като обръщам внимание на езика PHP:
- Инкрементиране на променлива: "++$i" е по-бързо от "$i++" - специално в PHP това се получава, защото второто изисква създаването на временна променлива. Ако не желаете да помните този факт - използвайте $i = $i+1. Същото естествено важи и за оператора за декрементиране (--);
- Проверка за дължина на низ: стандартно когато проверяваме дали един низ $string е с по-малко символи от дадена дължина $len ние правим "if (strlen($string)<$len) ...". Доста по-бързо е ако направим тази операция като "if (!isset($string[$len])) ...". На първо място не броим символите на $string - от там нататък всички допълнителни разяснения са бонус към бързината;
- Отпечатване на екрана: аз лично не съм виждал хора, които печатат на екрана с print или printf, но все пак ако има - echo е доста по-бързо. Това е защото то не връща стойност. За самото echo - параметризираното echo e по-бързо отколкото конкатенацията на низове в echo (за справка как се прави - прочетете документацията на echo). Друга тънкост е, че когато текстът е статичен, то е по-добре да затворите тага <?php с ?>, да напишете текста в чист HTML код и да си отворите отново <?php таг, за да продължите. С други думи - ако текста не е прекалено къс и си заслужава, то можете да минете въобще без echo;
- Граници за цикъл: много често хората пишат код като "for($i=0;$ i<count($arr); $i++)...". Вече знаем тънкостта за оператора за инкрементиране. Има обаче и още един проблем - функцията count се извиква на всяко завъртане на цикъла. Затова този код може да бъде пренаписан като: "for($i=0,$k=count($arr);$i<$k;$i=$i+1)...". За този конкретен пример също толкова добре се представя foreach, който по някакъв начин си е оптимизиран по описания начин вътрешно: "for($i in $arr)...";
- Кавички за низове: някои хора казват, че "низ" (с двойни кавички) се компилира по-бавно от 'низ'. Склонен съм да вярвам. Причината е, че двойните кавички позволяват вмъкване на стойност от променлива, например "стойността е $i" (тук ще се отпечата стойността на $i), докато единичните кавички интерпретират всичко вътре като символи, например 'стойността е $i' (тук ще се отпечатат просто символите '$' и 'i', но не и стойността на променливата). Ако все пак ви се наложи да отпечатвате стойността на променливата в текста - вместо двойни кавички използвайте функцията sprintf(). Резултатът от "парсването" е в пъти по-бърз!;
- Вмъкване на файлове: ако пишете кода си добре и не се нуждаете от проверка - използвайте require() вместо require_once(). Грубо казано ще си спестите един if :);
- Текущо време: малко хора знаят, но текущото време (функцията time()) се извиква при всяко зареждане на скрипт и се записва в $_SERVER[’REQUEST_TIME’]. Затова защо да извикваме time() отново, като можем да използваме директно вече записаната променлива?;
- Вложени логически оператори: колкото и да е дразнещо за пригледността на кода "if-else-if-else..." е по-бързо от "switch()";
- Извикване на елемент на масив: просто $arr['name'] е по-бързо от $arr[name]. Доколкото знам във втория случай компилаторът прави проверка дали имате предвид променлива или константа. Когато види, че не е променлива (не започва с '$') - ще го приеме за константа. В първия случай ние директно указваме константа;
- Локални дрещу глобални променливи: при всички случаи работата с локални променливи е по-бърза от работа с глобални.
Засега това са нещата, за които се сетих. Ако се сетя за още - ще допълвам.
7. Не е едно и също да се извика $_SERVER['REQUEST_TIME'] и time(). Първото ще върне времето,когато започнал скрипта, а при втория времето, когато е извикана функцията time(). Т.е. може да има разлика в секунди :) Всичко друго е вярно! 2 и 4 ми помогнаха доста! :)
Корекцията ти е правилна и всъщност аз съм го написал: "текущото време (функцията time()) се извиква при всяко зареждане на скрипт и се записва в $_SERVER[’REQUEST_TIME’]".
Е, ако ни се налага да вземем наистина абсолютно точно текущо време (например потребителя може да е отворил страницата, но да изчакваме негова реакция преди да вземем времето), то ще си извикваме time() - това е ясно.
Привет!
Прилагам линк по темата, който на мен ми беше полезен. Изложени са конкретни стойности (в %) при сравнение времето за изпълнение.
http://www.php.lt/benchmark/phpbench.php