Является ли оптимизация класса для модульного теста хорошей практикой или преждевременной? - PullRequest
5 голосов
/ 01 апреля 2011

Я видел (и искал) много вопросов в StackOverflow о преждевременной оптимизации - на улице говорят, что это корень всего зла. : P Признаюсь, я часто виновен в этом; Я не очень оптимизирую скорость за счет разборчивости кода, но я переписываю свой код логическими способами, используя типы данных и методы, которые кажутся более подходящими для задачи (например, в ActionScript 3, используя типизированный Vector вместо нетипизированного Array для итерации) и если я смогу сделать свой код более элегантным, я сделаю это. Обычно это помогает мне понять мой код, и я обычно знаю, почему я делаю эти изменения.

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

Таким образом, вот мой вопрос - разумно ли пытаться провести глубокую оптимизацию кода на уровне класса, поскольку ООП способствует модульности? Или это попадает в категорию преждевременной оптимизации? Я думаю, что если вы используете язык, который легко поддерживает модульное тестирование, вы можете тестировать, тестировать и оптимизировать класс, потому что он сам по себе является модулем, который принимает входные данные и генерирует выходные данные. Но, как один человек, пишущий код, я не знаю, стоит ли ждать, пока проект не будет полностью завершен, чтобы начать оптимизацию.

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

Надеюсь, этот вопрос подходит для StackOverflow - я не нашел другого, который бы прямо ответил на мой запрос.

Спасибо!

Редактировать: Размышляя над вопросом, я понимаю, что "профилирование" могло быть правильным термином вместо "модульного теста"; модульное тестирование проверяет, что модуль работает должным образом, а профилирование проверяет производительность. Кроме того, часть вопроса, который я должен был задать раньше, - не уменьшает ли профилирование отдельных модулей после их создания время профилирования после завершения приложения?

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

Ответы [ 5 ]

2 голосов
/ 01 апреля 2011

Я не очень оптимизирую скорость за счет разборчивости кода, но я переписываю свой код логическим образом, используя типы данных и методы, которые кажутся более подходящими для задачи [...], и если я смогуСделайте мой код более элегантным, я сделаю это.Это обычно помогает мне понять мой код

Это не совсем оптимизация , скорее рефакторинг для более чистого кода и лучшего дизайна *,Как таковая, это хорошая вещь, и она действительно должна практиковаться непрерывно, небольшими шагами.Дядя Боб Мартин (в своей книге Чистый код ) популяризировал правило бойскаута, адаптированное к разработке программного обеспечения: Оставьте код чище, чем вы его нашли .

Таким образом, если перефразировать ваш заглавный вопрос, да, реорганизация кода, чтобы сделать его тестируемым на модуле, является хорошей практикой.Одной из «крайностей» этого является Test Driven Development , где сначала пишется тест, а затем добавляется код, выполняющий тест.Таким образом, код создается модульно-тестируемым с самого начала.

* Чтобы не быть придирчивым, просто полезно уточнить общую терминологию и убедиться, что мы используем одни и те же термины в одном и том же значении.

1 голос
/ 01 апреля 2011

Да, вам следует пропустить оптимизацию для модульного теста.Оптимизация, когда требуется, обычно делает код более сложным.Стремитесь к простоте.Если вы оптимизируете для модульного теста, вы можете де-оптимизировать для производства.

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

РЕДАКТИРОВАТЬ: Дезоптимизация может произойти, когда обрабатываемые данные различаются по размеру.Скорее всего, это произойдет с классами, которые работают с наборами данных.Реакция может быть линейной, но изначально медленной, по сравнению с геометрической и изначально быстрой.Если в модульном тесте используется небольшой набор данных, то для модульного теста можно выбрать геометрическое решение.Когда производство попадает в класс с большим набором резервуаров производительности данных.

Алгоритмы сортировки являются классическим случаем для такого рода поведения и, как следствие, де-оптимизации.Многие другие алгоритмы имеют сходные характеристики.

EDIT2: Моя самая успешная оптимизация была процедура сортировки для отчета, где данные были сохранены на диске в файле отображения памяти.Время сортировки было разумным при умеренных размерах данных, которые не требовали доступа к диску.При использовании больших наборов данных обработка данных может занять несколько дней.Начальные сроки отчета показали;выбор данных 3 минуты, сортировка данных 3 дня и отчет 3 минуты.Расследование такого рода показало, что это была полностью неоптимизированная пузырьковая сортировка (n-1 полных проходов для набора данных размером n), примерно n квадратов в больших обозначениях O.Изменение алгоритма сортировки сократило время сортировки для этого отчета до 3 минут.Я не ожидал, что модульный тест охватит этот случай, и исходный код был настолько простым (быстрым), насколько это возможно для небольших наборов.Замена была намного более сложной и медленной для очень маленьких наборов, но обрабатывать большие наборы быстрее с более линейной кривой, n log n в больших обозначениях O.(Примечание: оптимизация не была предпринята, пока у нас не было показателей.)

На практике я стремлюсь к десятикратному улучшению процедуры, которая занимает не менее 50% времени работы модуля.Достижение этого уровня оптимизации для рутины, использующей 55% времени выполнения, сэкономит 50% общего времени выполнения.

1 голос
/ 01 апреля 2011

Я твердо верю, что вы никогда не должны снижать читабельность кода и хороший дизайн из-за оптимизации производительности.

Если вы пишете код, для которого критична производительность, возможно, можно снизить стиль и четкость кода, но это не относится к среднему корпоративному приложению.Оборудование развивается быстро и становится дешевле с каждым днем.В конце концов, вы пишете код, который будут читать другие разработчики, поэтому вам лучше поработать над этим!

Всегда красиво читать код, который был тщательно создан , где на каждом пути есть тест, который помогает вам понять, как его следует использовать.Мне все равно, если это на 50 мс медленнее, чем альтернатива спагетти, которая делает много сумасшедших вещей.

1 голос
/ 01 апреля 2011

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

Например,Вы можете потратить много времени на оптимизацию класса, но обнаружите, что узким местом в вашем приложении является задержка в сети или аналогичный фактор, который намного дороже с точки зрения времени выполнения.Поскольку с самого начала у вас нет полной картины, преждевременная оптимизация приводит к неоптимальному использованию вашего времени.В этом случае вы, вероятно, предпочли бы устранить проблему с задержкой, чем оптимизировать код класса.

1 голос
/ 01 апреля 2011

Правда, оптимизацию, я считаю, следует оставить в качестве конечной задачи (хотя хорошо знать, куда вам, возможно, придется вернуться и оптимизировать при написании первого черновика).Это не значит, что вы не должны повторно анализировать вещи, чтобы поддерживать порядок и чистоту в коде.Это значит, что если что-то в настоящее время служит цели и не соответствует требованию приложения, то сначала необходимо выполнить требования, так как в конечном итоге они являются тем, за что вы отвечаете (если требования не включают в себя подробности о максимальном времени запроса иличто-то в этом роде).Я также согласен с методологией Корина: сначала постройте для функции, если позволяет время, оптимизируйте содержание вашего сердца (или теоретический предел, в зависимости от того, что наступит раньше).

...