Как избежать опасности оптимизации при проектировании для неизвестного? - PullRequest
3 голосов
/ 22 сентября 2008

Два партнера:

1) Скажем, вы разрабатываете приложение нового типа и разрабатываете новые алгоритмы для выражения концепций и контента - имеет ли смысл попытаться активно не рассматривайте методы оптимизации на этом этапе, даже если в глубине души вы боитесь, что это может закончиться как O (N!) для миллионов элементов?

2) Если это так, скажем, чтобы не ограничивать классную функциональность, которую вы могли бы оптимизировать после запуска проверки концепции - как вы удерживаете себя от этой привычки программистов на всю жизнь? ? Я пробовал умственные упражнения, бумажные заметки, но я вырос, по сути, считая тактовые циклы на ассемблере, и я постоянно нахожу вето на потенциальных решениях из-за слишком расточительных действий, прежде чем полностью учитывать функциональную ценность.

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

Ответы [ 14 ]

6 голосов
/ 22 сентября 2008

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

Ключ в том, чтобы сохранить здравомыслие.

Если вы обнаружите, что пишете алгоритм Theta (N!), Который, как ожидается, будет масштабироваться, то вы с ума сошли. Вам придется выбросить его, так что вы можете начать поиск лучшего алгоритма, который вы могли бы использовать.

Если вы беспокоитесь о том, займет ли часть кода Pentium, который выполняется точно один раз за нажатие клавиши пользователем, 10 или 10 Кбайт, то вы с ума сошли. Процессор простаивает на 95%. Дайте ему десять тысяч жалких циклов. Поднимите билет улучшения, если нужно, но медленно отойдите от ассемблера.

Однажды нужно решить, является ли проект «написать исследовательский прототип, а затем превратить его в реальный продукт» или «написать исследовательский прототип». С очевидным ожиданием, что, если исследование будет успешным, в будущем появится еще один связанный проект.

В последнем случае (который из комментариев звучит как то, что у вас есть) вы можете позволить себе написать что-то, что работает только для N <= 7 и даже тогда приводит к отключениям отсюда в Цинциннати. Это все еще то, что ты не был уверен, что сможешь сделать. Как только вы почувствуете проблему, у вас будет лучшее представление о проблемах производительности. </p>

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

5 голосов
/ 22 сентября 2008

Мой большой ответ - Разработка через тестирование . Записывая все свои тесты заранее, вы заставляете себя писать только код, достаточный для реализации искомого поведения. Если время и тактовые циклы становятся требованием, вы можете написать тесты, чтобы охватить этот сценарий, а затем реорганизовать свой код для удовлетворения этих требований.

2 голосов
/ 30 сентября 2008

Прежде всего, люди утверждают, что финиш - это единственное, что имеет значение (или почти).

Но если вы закончите продукт со сложностью O (N!) По основному алгоритму, вы, как правило, не завершили его! У вас неполный и неприемлемый продукт в 99% случаев.

Разумная производительность является частью рабочего продукта. Идеальной производительности может и не быть. Если вы заканчиваете текстовый редактор, которому требуется 6 ГБ памяти, чтобы написать короткую заметку, то вы вообще не закончили продукт, у вас есть только пустая трата времени. Вы должны всегда помнить, что это не только доставка кода Это делает продукт завершенным, обеспечивает его способность удовлетворять потребности клиентов / пользователей. Если у вас ничего не получится, это ничего не значит, что вы закончили писать код в расписании.

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

2 голосов
/ 22 сентября 2008

«Сначала заставьте его бежать. Затем заставьте его бежать быстро.»

или

"Чтобы закончить первым, сначала нужно закончить."

Медленное существующее приложение обычно лучше, чем сверхбыстрое несуществующее приложение.

2 голосов
/ 22 сентября 2008

Старая линия Кнута гласит: «Мы должны забыть о малой эффективности, скажем, в 97% случаев: преждевременная оптимизация - корень всего зла». От O (N!) До O (поли (N)) - это не «маленькая эффективность»!

Лучший способ справиться с типом 1 - начать с самой простой вещи, которая могла бы работать (O (N!) Не может работать, если вы не масштабируете более пары десятков элементов!), И инкапсулировать ее из остальной части приложение, чтобы вы могли переписать его в лучшую сторону, предполагая, что возникнет проблема с производительностью.

2 голосов
/ 22 сентября 2008

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

2 голосов
/ 22 сентября 2008

Оптимизация не совсем опасна; хорошо думать в некоторой степени о скорости при написании кода, потому что он мешает вам реализовывать медленные и грязные решения, когда что-то проще и быстрее будет делать. Это также дает вам возможность проверить, будет ли что-то практичным или нет.

Худшее, что может случиться, - это разработать большую программу, явно игнорирующую оптимизацию, а затем вернуться и обнаружить, что весь ваш проект совершенно бесполезен, поскольку его нельзя оптимизировать, не переписав его полностью . Этого никогда не произойдет, если вы будете учитывать все при написании, а часть этого «всего» - потенциальные проблемы с производительностью.

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

Поскольку это было написано полностью игнорируя скорость, это был беспорядок; у него были тонны memcpys, несмотря на то, что они никогда не были необходимы, его код обработки TS был абсурдно медленным (фактически он анализировал каждый отдельный пакет TS несколько раз) и так далее. Он обрабатывал всего 40 потоков за раз вместо тысяч, которые предполагалось, и когда пришло время использовать его для VOD, нам пришлось вернуться и потратить огромное количество времени на его очистку и переписывание больших частей кода. это.

1 голос
/ 10 ноября 2009

Мне нравится этот вопрос, поэтому я даю ответ, хотя другие уже ответили на него.

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

У меня сложилось впечатление, что те, кто добился прогресса, больше интересовались написанием программ, которые делали бы что-то интересное, чем что-то быстрое. Фактически, время, потраченное на заботу о производительности, в основном вычиталось из времени, затрачиваемого на размышления об интересном поведении.

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

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

.

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

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

Вот пример настройки приложения, которое было написано так, как это обычно преподается.

1 голос
/ 22 сентября 2008

Исходя из ответа onebyone , существует большая разница между оптимизацией кода и оптимизацией алгоритма.

Да, на данном этапе оптимизация кода будет иметь сомнительную выгоду. Вы не знаете, где настоящие узкие места, вы не знаете, будут ли проблемы со скоростью.

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

1 голос
/ 22 сентября 2008

Я думаю, что вполне разумно забыть о O (N!) Худшем случае для алгоритма. Сначала вам нужно определить, что данный процесс возможен вообще. Имейте в виду, что закон Мура все еще действует, поэтому даже плохие алгоритмы займут меньше времени через 10 или 20 лет!

Сначала оптимизируйте для дизайна - например, заставь это работать сначала :-) Тогда оптимизируй для производительности. Это тот тип компромисса, который программисты Python делают по своей сути. Программируя на языке, который обычно медленнее во время выполнения, но имеет более высокий уровень (например, по сравнению с C / C ++) и, следовательно, быстрее развивается, программисты на Python могут достичь довольно многого. Затем они сосредоточены на оптимизации.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...