GetInfo.Ru – Компьютерная библиотека
Последние поступления
Как выбрать систему управления базы данных
Базы данных03/09/14
Этапы загрузки UNIX (в схеме)
Unix27/03/12
Gatewall Antispam: тотальный контроль электронной почты
Спам21/04/11
Мастер-класс: создаем Интернет-магазин (Часть 1)
Обзоры ПО20/04/11
CorelDRAW Graphics Suite X5: Что нового?
Обзоры ПО20/07/10
Добавить статью
Самые читаемые материалы
PHP: авторизация доступа(81690)
Как сделать Интернет-магазин?(64586)
Сессии в PHP(53809)
Веб-сайт: сборка по кирпичикам(28775)
СЕССИИ - обучение и /правильное/ использование(19215)
Всего статей: 793Всего авторов: 364Подразделов: 47Добавлено за сутки: 0
Статьи  СТАТЬИ Форум  ФОРУМ Рейтинг  РЕЙТИНГ Поиск  ПОИСК Контакты  КОНТАКТЫ
» Главная » PHP » Оптимизация программ на PHP

Оптимизация программ на PHP


Дмитрий Бородин
dima@php.spb.ru
http://php.spb.ru/

Страницы: [ 1 ] [ 2 ]

В этой статье на простых и очевидных примерах рассказано о некоторых способах оптимизировать любую (готовую) программу, не меняя ни одного алгоритма. Для такой оптимизации можно даже написать программу для автоматического выполнения всех рекомендаций, все они очень простые (правда, для начала придется написать парсер пхп-кода).

Выносите $переменные из "текстовых строк" - ускорение 25-40%

Одна и таже операция присваивания (либо echo/print для вывода на экран) в зависимости от того, заключены ли переменные в кавычеки или нет, сильно влияет на скорость. В первом и втором вариантах добавлены пробелы, чтобы выравнять размер общего кода для парсинга.

  1. {$x="test".$test;    }
  2. {$x="test $test";    }
  3. {$x="test";$x.=$test;}
Переменная $test содержит строку "1234567890".

счетчик кол-во
вызовов
общее
вpемя
сpеднее
вpемя
% от min% от maxобщее
время
test N113.59113.591100.0%70.9%


test N215.06165.061640.9%100.0%


test N314.98704.987038.9%98.5%


Итак, никогда не пишите $a="$b", ибо это затормозит программу (в этой строке) на 40%.

Однако, если у вас большая строка, где много текста и переменных, различия в скорости уменьшаются, т.к. общие затраты на парсинг становятся намного больше, чем разные по эффективности команды. Но почему бы и не увеличить скорость программы (строк присваивания) почти на четверть таким простым методом?

  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;}
счетчик кол-во
вызовов
общее
вpемя
сpеднее
вpемя
% от min% от maxобщее
время
test N117.68947.689400.0%66.0%


test N219.55159.551524.2%82.0%


test N3111.650611.650651.5%100.0%


Короткие переменные не более 7 символов - ускорение 15%

Как влияет длина имен переменных на скорость программы? Если использовать очень длинные переменные - очевидно, что весьма сильно. Однако и с короткими именеми не все просто:

  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;}
выдает предсказуемый результат:

счетчик кол-во
вызовов
общее
вpемя
сpеднее
вpемя
% от min% от maxобщее
время
test N111.70001.700000.0%68.5%


test N211.70281.702800.2%68.6%


test N311.71821.718201.1%69.2%


test N411.72281.722801.3%69.4%


test N511.75361.753603.2%70.6%


test N611.75041.750403.0%70.5%


test N711.77991.779904.7%71.7%


test N811.96041.960415.3%78.9%


test N911.98651.986516.9%80.0%


test N1012.01192.011918.3%81.0%


test N1112.03022.030219.4%81.7%


test N1212.12882.128825.2%85.7%


test N1312.48352.483546.1%100.0%


Переменные от 32 символов могут тормознуть программу почти на половину.

Но если заполнять пробелами (" "), чтобы все строки "$x=1; ..." по длине занимали одно и тоже расстояние, то получается вот что:

  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;    }
счетчик кол-во
вызовов
общее
вpемя
сpеднее
вpемя
% от min% от maxобщее
время
test N112.11672.116701.9%83.3%


test N212.07662.076600.0%81.7%


test N312.09372.093700.8%82.4%


test N412.08212.082100.3%81.9%


test N512.11452.114501.8%83.2%


test N612.09212.092100.7%82.3%


test N712.10762.107601.5%82.9%


test N812.30582.305811.0%90.7%


test N912.30462.304611.0%90.7%


test N1012.31072.310711.3%90.9%


test N1112.31112.311111.3%90.9%


test N1212.36802.368014.0%93.2%


test N1312.54182.541822.4%100.0%


Уж как комментировать тест переменной из одного символа (на 2% медленне самого быстрого) - не знаю... Наверно, тесты имеют большую погрешность. Предлагаю кому-нибудь запустить тест на час (исходники теста внизу страницы).

Одно ясно - при длине переменных в 8 и более символов происходит резкое снижение производительности, до 15%! А команд, включающих названия переменных, очень много. Еще один менее резкий скачек на переменных с именем 16 символов в длину и более. А в остальных случаях - чем больше, тем дольше, весьма линейная зависимость.

Вывод - не используйте переменны из 8 и более символов, выиграете 15% скорости (вернее, сэкономите).

Тормозят ли массивы в PHP? Вернее, как именно. Ускорение 40%.

А вот и не тормозят. Я где-то читал, якобы ассоциативные массивы в PHP жутко тормозят. Конечно, тест простой, но большой разницы между непрерывным простым (1), простым (2) и ассоциативным (3) массивами нет (элемент 0000 преобразуется в 0 - это же число, а не строка). И уж явно не тормозят "не ассоциативные не сплошные массивы".

  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;     }
счетчик кол-во
вызовов
общее
вpемя
сpеднее
вpемя
% от min% от maxобщее
время
test N115.39245.392401.1%28.0%


test N215.33325.333200.0%27.7%


test N315.76515.765108.1%29.9%


test N417.65437.654343.5%39.7%


test N516.66496.664925.0%34.6%


test N616.62216.622124.2%34.3%


test N7119.282019.2820261.5%100.0%


Что тут можно комментировать.. все очевидно. Доступ к элементу одномерного ассоциативного массива по имени, не заключенному в кавычки, тормозит процесс на треть (относительно того же примера, но в кавычках). А вот в двухмерном массиве программа работает медленне аж в 2.5 раза! После такого теста хочешь не хочешь, а в любой программе пожертвуешь удобством - обращение к элементам массива по имени без кавычек.

Выносите многомерные массивы из "текстовых строк" - ускорение 25-30%. Одномерные можно не выносить.

При использовании многомерных массивов в строках наблюдается заметное снижение скорости Из-за многомерности нужно заключать переменные в парные фигурные скобки.

  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";}
счетчик кол-во
вызовов
общее
вpемя
сpеднее
вpемя
% от min% от maxобщее
время
test N113.53693.536900.0%69.9%


test N215.06055.060543.1%100.0%


test N314.60174.601730.1%90.9%


Тот же пример с ассоциативным 3-х мерным массивом, но с обращением к элементу по его индексному номеру:

  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";}
счетчик кол-во
вызовов
общее
вpемя
сpеднее
вpемя
% от min% от maxобщее
время
test N113.30123.301200.0%73.1%


test N214.16674.166726.2%92.3%


test N314.51454.514536.8%100.0%


Разница в 1 и 2 вариантах очень мала. Это говорит, что потери на не эффективное использование кавычек не слишком большое, чем доступ к массивам (см. тесты в первой главе).

  1. {$x="test".$myarray["test"]."test";}
  2. {$x="test$myarray[test]test";      }
  3. {$x="test{$myarray[test]}test";    }
счетчик кол-во
вызовов
общее
вpемя
сpеднее
вpемя
% от min% от maxобщее
время
test N112.84952.849500.0%80.9%


test N212.95192.951903.6%83.9%


test N313.52023.520223.5%100.0%


А теперь, на основании всех трех тестов, однозначный вывод: использовать фигурные скобки для обозначения границ имени элемента многомерного массива НЕЛЬЗЯ. Это сильно снижает скорость работы - 25-30% (в третьем варианте от простого добавления скобок скорость понизилась на четверть). Не использовать скобки нельзя. Следовательно, единственный способ не терять 30% скорости - выносить многомерные массивы из скобок.

Такой же тест, но для одномерных:

  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";}
счетчик кол-во
вызовов
общее
вpемя
сpеднее
вpемя
% от min% от maxобщее
время
test N116.58436.584300.0%78.0%


test N216.77706.777002.9%80.3%


test N318.44068.440628.2%100.0%


Сравнивая два последних теста очевидно, что одномерные массивы можно и не выносить, потери всего 3-4% (а вот на простых переменных - потери 25-40%!).

 
08.02.2003
Версия для печати Версия для печати Запомнить ссылку Запомнить ссылку
Ваша оценка:  1   2   3   4   5     

 О проектеПерепечаткаАвторамПартнерыО нас пишут
Наверх
©2003—2007. GETINFO.RU. ВСЕ ПРАВА ЗАЩИЩЕНЫ.