C, PHP, VB, .NET

Дневникът на Филип Петров


* Няколко съвета за по-бързи програми на PHP

Публикувано на 22 март 2010 в раздел ОСУП.

Тази статия определено не е свързана със „сигурно програмиране“, но реших, че може все пак да влезне в употреба. През годините съм слушал много съвети за това как да се оптимизира код така, че да отнема минимални ресурси. Естествено основната тежест в такава задача пада върху алгоритмите. Има обаче и други, по-дребни „трикчета“, които отнемат някоя друга милисекунда от времето за изпълнение. Честно казано никога не съм бил привърженик на този род оптимизации, защото най-често правят кода нечетим. Въпреки това ще споделя някои неща, които съм запомнил през времето, като обръщам внимание на езика PHP:

  1. Инкрементиране на променлива: „++$i“ е по-бързо от „$i++“ – специално в PHP това се получава, защото второто изисква създаването на временна променлива. Ако не желаете да помните този факт – използвайте $i = $i+1. Същото естествено важи и за оператора за декрементиране (–);
  2. Проверка за дължина на низ: стандартно когато проверяваме дали един низ $string е с по-малко символи от дадена дължина $len ние правим „if (strlen($string)<$len) …“. Доста по-бързо е ако направим тази операция като „if (!isset($string[$len])) …“. На първо място не броим символите на $string – от там нататък всички допълнителни разяснения са бонус към бързината;
  3. Отпечатване на екрана: аз лично не съм виждал хора, които печатат на екрана с print или printf, но все пак ако има – echo е доста по-бързо. Това е защото то не връща стойност. За самото echo – параметризираното echo e по-бързо отколкото конкатенацията на низове в echo (за справка как се прави – прочетете документацията на echo). Друга тънкост е, че когато текстът е статичен, то е по-добре да затворите тага <?php с ?>, да напишете текста в чист HTML код и да си отворите отново <?php таг, за да продължите. С други думи – ако текста не е прекалено къс и си заслужава, то можете да минете въобще без echo;
  4. Граници за цикъл: много често хората пишат код като „for($i=0;$ i<count($arr); $i++)…“. Вече знаем тънкостта за оператора за инкрементиране. Има обаче и още един проблем – функцията count се извиква на всяко завъртане на цикъла. Затова този код може да бъде пренаписан като: „for($i=0,$k=count($arr);$i<$k;$i=$i+1)…“. За този конкретен пример също толкова добре се представя foreach, който по някакъв начин си е оптимизиран по описания начин вътрешно: „for($i in $arr)…“;
  5. Кавички за низове: някои хора казват, че „низ“ (с двойни кавички) се компилира по-бавно от ‘низ’. Склонен съм да вярвам. Причината е, че двойните кавички позволяват вмъкване на стойност от променлива, например „стойността е $i“ (тук ще се отпечата стойността на $i), докато единичните кавички интерпретират всичко вътре като символи, например ‘стойността е $i’ (тук ще се отпечатат просто символите ‘$’ и ‘i’, но не и стойността на променливата). Ако все пак ви се наложи да отпечатвате стойността на променливата в текста – вместо двойни кавички използвайте функцията sprintf(). Резултатът от „парсването“ е в пъти по-бърз!;
  6. Вмъкване на файлове: ако пишете кода си добре и не се нуждаете от проверка – използвайте require() вместо require_once(). Грубо казано ще си спестите един if :);
  7. Текущо време: малко хора знаят, но текущото време (функцията time()) се извиква при всяко зареждане на скрипт и се записва в $_SERVER[’REQUEST_TIME’]. Затова защо да извикваме time() отново, като можем да използваме директно вече записаната променлива?;
  8. Вложени логически оператори: колкото и да е дразнещо за пригледността на кода „if-else-if-else…“ е по-бързо от „switch()“;
  9. Извикване на елемент на масив: просто $arr[‘name’] е по-бързо от $arr[name]. Доколкото знам във втория случай компилаторът прави проверка дали имате предвид променлива или константа. Когато види, че не е променлива (не започва с ‘$’) – ще го приеме за константа. В първия случай ние директно указваме константа;
  10. Локални дрещу глобални променливи: при всички случаи работата с локални променливи е по-бърза от работа с глобални.

Засега това са нещата, за които се сетих. Ако се сетя за още – ще допълвам.

 



3 коментара


  1. Мартин каза:

    7. Не е едно и също да се извика $_SERVER[‘REQUEST_TIME’] и time(). Първото ще върне времето,когато започнал скрипта, а при втория времето, когато е извикана функцията time(). Т.е. може да има разлика в секунди :) Всичко друго е вярно! 2 и 4 ми помогнаха доста! :)

  2. Корекцията ти е правилна и всъщност аз съм го написал: „текущото време (функцията time()) се извиква при всяко зареждане на скрипт и се записва в $_SERVER[’REQUEST_TIME’]“.

    Е, ако ни се налага да вземем наистина абсолютно точно текущо време (например потребителя може да е отворил страницата, но да изчакваме негова реакция преди да вземем времето), то ще си извикваме time() – това е ясно.

  3. Привет!
    Прилагам линк по темата, който на мен ми беше полезен. Изложени са конкретни стойности (в %) при сравнение времето за изпълнение.
    http://www.php.lt/benchmark/phpbench.php

Добави коментар

Адресът на електронната поща няма да се публикува


*