Как проводить рефакторинг?
В предыдущей статье мы с Вами разобрали что такое рефакторинг. А в этой статье мы разберём пример рефакторинга конкретного работающего кода. После прочтения этой статьи Вы узнаете, как проводить рефакторинг.
Предположим, у нас есть такой PHP-код:
<?php
$array = array();
for ($i = 0; $i < 100000; $i++) {
$array[$i] = $i;
}
$result = 0;
for ($i = 0; $i < count($array); $i++) {
$result += round($array[$i] * sqrt($i));
}
echo $result;
?>
Это правильно работающий код, однако, он далеко не идеален. Наша с Вами задача увеличить быстродействие и уменьшить количество кода. Что касается стилистики, то тут проблем никаких нет: всё понятно и всё прекрасно читается.
Начнём с быстродействия. Я уже писал, как узнать время выполнения скрипта, поэтому повторяться не буду.
Итак, замерив время работы данного скрипта у меня получилось примерно 0.30 секунды. Первое, что можно сразу исправить - это создание массива. Дело в том, что в PHP есть очень простая функция range(), которая делает всё ровно так же, что и у нас, только быстрее:
<?php
$array = range(0, 99999);
$result = 0;
for ($i = 0; $i < count($array); $i++) {
$result += round($array[$i] * sqrt($i));
}
echo $result;
?>
Время выполнения уже 0.24 секунды, неплохо выиграли, плюс количество кода резко сократилось.
Теперь разберём очень популярный вид дублирования, а именно в указании условия выхода из цикла. В данном коде мы в каждой итерации вычисляем длину массива. Но зачем? Ведь она постоянная и никак не меняется. Эту "ошибку" допускают практически все профессионалы, в том числе, и я. В основном, просто по привычке, потому что так пишут все. И стоит отметить, если массив не очень большой, то с точки зрения читабельности так и стоит оставить, но когда массив огромный, то надо писать так:
<?php
$array = range(0, 99999);
$result = 0;
$count = count($array);
for ($i = 0; $i < $count; $i++) {
$result += round($array[$i] * sqrt($i));
}
echo $result;
?>
Время выполнения уже 0.17 секунды, а это уже большой выигрыш во времени.
Теперь займёмся количеством кода. Мы уже с Вами в этом направлении поработали, и нам осталось лишь убрать ненужные фигурные скобки у цикла. Они там просто не нужны, поскольку внутри цикла всего лишь один оператор. В результате, код получился таким:
<?php
$array = range(0, 99999);
$result = 0;
$count = count($array);
for ($i = 0; $i < $count; $i++) $result += round($array[$i] * sqrt($i));
echo $result;
?>
Можно было ещё, конечно, вообще обойтись без массива, а в цикле подставлять вместо $array[$i], просто $i, но предположим, что по условиям задачи нам нужно было создать массив. Всё, рефакторинг мы завершили и давайте подведём итог. Производительность скрипта увеличилась почти в 2 раза, количество строк уменьшилось в 1.5 раза. Как видите, даже в таком, казалось бы, простом скрипте, мы умудрились так сильно всё улучшить. А уж про те же движки, я вообще молчу, там можно вечно проводить рефакторинг.
-
- Михаил Русаков
Комментарии (1):
Спасибо, статья полезная. А про $count = count($array); я знал давно, и уже вошло в привычку так делать.
Ответить
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.