Сравнение двух рефакторингов по скорости 
Давайте еще раз посмотрим на два варианта кода, которые я предложил в рамках батла по рефакторингу. Посмотрим и решим, какой из вариантов лучше.
Напомню, первый вариант выглядел так:
$files = $files ? $files : $this->files;
foreach($files as $file) {
if (‘file’ == $file[‘type’]) {
file_put_contents($path . $file[‘name’], $file[‘content’]);
}
if (‘dir’ == $file[‘type’] and !is_dir($path . $file[‘name’])) {
mkdir($path . $file[‘name’]);
}
if (isset($file[‘items’])) {
$this->generate2($file[‘items’], $path . $file[‘name’] . DIRECTORY_SEPARATOR);
}
}
}
А второй так:
$files = $files ? $files : $this->files;
foreach($files as $fileOrDir) {
$fileOrDirObject = FileObjectsFactory::create($fileOrDir, $path);
$fileOrDirObject->create();
isset($fileOrDir[‘items’]) and $this->generate($fileOrDir[‘items’], $path . $fileOrDir[‘name’] . DIRECTORY_SEPARATOR);
}
}
Я осознанно опустил все лишнее классы и методы, оставив только функцию, которую хотел улучшить в результате рефакторинга. Сразу оговорюсь, что мне не нравится рекурсия, которая была в первом варианте и пока осталась во втором. В ближайшее время я планирую с ней разобраться с помощью RecursiveIterator. Кому интересно, могут дождаться следующего рефакторинга и посмотреть, как я это сделал.
Относительно кода выше. Мое мнение такое - второй вариант гораздо понятнее, а поэтому однозначно лучше. Однако, многим программистам для принятия решения одной выразительности кода недостаточно. Это связано с тем, что, кроме выразительности, еще есть такая штука как производительность. Поэтому чтобы ответить на немой вопрос читателей - “как там дела с производительностью?” я решил посмотреть, кто кого сделает по скорости.
Не трудно догадаться, что второй вариант должен быть медленнее первого. Это вполне логично, так как вызов функций - достаточно дорогая операция. Весь вопрос в том, во сколько раз первый вариант быстрее. Можете ради интереса сделать предположение о том, какая разница будет получена в итоге. Возможно, кого-то результат удивит или, наоборот, расстроит. Так или иначе, давайте посмотрим на цифры.
Отмечу, что скорость выполнения первой функции зависит от содержания массива. Наилучший вариант - это когда массив $files состоит из объектов одного типа. Например, только из файлов. А наихудший вариант - когда в массиве одинаковое количество файлов и каталогов. Однако разница между худшим и лучшим вариантом оказалась настолько мизерной (в районе 5%), что я решил ее не учитывать.
Ниже два скриншота, содержащие результаты профилирования для массива состоящего из 500 файлов и 500 директории (первый скриншот - для первого варианта, второй - для второго):
Проанализируем данные: первый вариант выполнялся 77 249 единиц времени (это не миллисекунды), а второй вариант 141 613. Путем несложных вычислений получаем, что первый вариант быстрее в 1.8 раза (если честно, я ожидал больше).
Вывод: подобная потеря производительности может быть существенной, только если работать со структурами содержащими 10-ки тысяч объектов, а это с учетом специфики функции маловероятно. Вообще, генерация дерева файлов и каталогов - не такая частая операция, чтобы экономить на ней. Поэтому, несмотря на потерю производительности, я выбираю второй вариант.
Интересно узнать, какой вариант выбрали вы и почему?


подписаться на блог
Тормоз
Гость
Второй, конечно, он гораздо лучше читается, если бы не тернарные операторы )
А про баттлы я вспомнил, можно же ещё генератор ников помучать. Я его давно делал, идеальный претендент для рефакторинга - когда не очень много, задача простенькая. Есть к чему стремиться (дофига идей, как улучшить), изначальный код довольно отстойный, писал его год назад.
Тут про генератор и там же исходники - http://brokenbrake.biz/2009/07/25/gen-3
Я вот сейчас по улице шёл и думал об этом. Можно ведь ещё двух-, трёхсловные ники делать с прилагательными, учётом пола и т. п. И даже рифмованные.
Типа Стрелок без чулок, или Картавая белка.
Или Отврат с лисичкой. Вобщем, дофига вариантов
Тормоз
Гость
Когда не очень много = кода не очень много. Блин, какая-то логическая опечатка.
Evgeny Sergeev
Веб-разработчик, автор блога codeart.ru
Тормоз, вместе с рекурсией избавлюсь от тернарных операторов
Тормоз
Гость
Хм, сейчас внимательней посмотрел, удивила такая строчка:
$files = $files ? $files : $this->files;
И что бы это значило? При каких условиях здесь может выполнится $this->files?
Leave a Reply