// codeart.ru / Главная / Сравнение двух рефакторингов по скорости Форум

Сравнение двух рефакторингов по скорости rss подписка

Автор: Evgeny Sergeev

Давайте еще раз посмотрим на два варианта кода, которые я предложил в рамках батла по рефакторингу. Посмотрим и решим, какой из вариантов лучше.

Напомню, первый вариант выглядел так:

public function generate($files = array(), $path = ) {
        $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);
             }
        }
    }

А второй так:

public function generate($files = array(), $path = ) {
        $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-ки тысяч объектов, а это с учетом специфики функции маловероятно. Вообще, генерация дерева файлов и каталогов - не такая частая операция, чтобы экономить на ней. Поэтому, несмотря на потерю производительности, я выбираю второй вариант.

Интересно узнать, какой вариант выбрали вы и почему?

  1. Второй, конечно, он гораздо лучше читается, если бы не тернарные операторы )

    А про баттлы я вспомнил, можно же ещё генератор ников помучать. Я его давно делал, идеальный претендент для рефакторинга - когда не очень много, задача простенькая. Есть к чему стремиться (дофига идей, как улучшить), изначальный код довольно отстойный, писал его год назад.

    Тут про генератор и там же исходники - http://brokenbrake.biz/2009/07/25/gen-3

    Я вот сейчас по улице шёл и думал об этом. Можно ведь ещё двух-, трёхсловные ники делать с прилагательными, учётом пола и т. п. И даже рифмованные.

    Типа Стрелок без чулок, или Картавая белка.
    Или Отврат с лисичкой. Вобщем, дофига вариантов :)

  2. Когда не очень много = кода не очень много. Блин, какая-то логическая опечатка.

  3. Тормоз, вместе с рекурсией избавлюсь от тернарных операторов

  4. Хм, сейчас внимательней посмотрел, удивила такая строчка:

    $files = $files ? $files : $this->files;

    И что бы это значило? При каких условиях здесь может выполнится $this->files?

Leave a Reply

« Продолжаем батл по рефакторингу Какое авто взять? »

 

детские обои .