Когда происходит «оптимизация кода» == «структурирование данных»?

9

В недавней статье ycombinator перечислены комментарии с принципами великого программиста.

#7. Хороший программист: я оптимизирую код. Лучший программист: я структурирую данные. Лучший программист: какая разница?

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

Новая Александрия
источник
2
Список, на который вы ссылаетесь, содержит кучу интересных вещей. Спасибо.
DeveloperDon
На этот вопрос (который я задал) есть ответ, в котором также упоминается эта цитата: programmers.stackexchange.com/q/168013/15028
TCSGrad

Ответы:

16

В девяти случаях из десяти, когда вы правильно структурируете свой код / ​​модели, оптимизация станет очевидной. Сколько раз вы видели гнездо шершней и находили его совершенно неоптимальным, когда после его реструктуризации множество избыточных стало чрезвычайно очевидным.

Дизайнер знает, что достиг совершенства не тогда, когда нечего добавить, а когда нечего убрать. - Антуан де Сент-Экзюпери

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

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

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

Джимми Хоффа
источник
1
Это не говорит о «данных» и о том, что «нет никакой разницы между оптимизацией кода и структурированием данных». Оптимизация кода не приводит к реструктуризации неверных данных, если только это не какой-то самоусвояющийся, полный по Тьюрингу аппарат
Новая Александрия,
1
@NewAlexandria упомянутая модель - это «данные». Часто плохой код и плохая модель идут рука об руку. Исправление одного влечет за собой исправление другого.
1
@NewAlexandria Я имею в виду структурирование ваших моделей как структурирование «данных», моя точка зрения заключается просто в структурировании данных / кода как синонимов, поскольку они являются частью системы в целом и взаимозависимы. Для структурирования одной из скважин также потребуются изменения другой, возможно, это больше того, что вы искали? Я пытался объяснить, как структура и оптимизация одинаковы, а не как код и данные связаны, может быть, я неправильно понял ваш вопрос, если это вас смущало?
Джимми Хоффа
Я думаю, что это ближе всего к выяснению правильного смысла темы. Я, конечно, знал, как это работает, но надеялся, что кто-то увидит что-то более глубокое в вопросе, который я привел.
Новая Александрия
4

Я думаю, что автор намекает, что любая реструктуризация данных приводит к реструктуризации кода. Таким образом, реструктуризация данных с целью оптимизации вашей системы также заставит вас оптимизировать код, вызывая вопрос: «В чем разница?» ответ.

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

dasblinkenlight
источник
Интересно, что у меня сложилось впечатление, что темой утверждения было сравнение между структурой и оптимизацией, а не отношение между кодом и данными, хотя вы абсолютно правы относительно отношения и того, что оно также объясняет это. Чувствуется, как собирать коан :)
Джимми Хоффа
Иногда реструктуризация данных допускает реструктуризацию кода, но я думаю, что иногда, когда вы закончите, новый код имеет очень мало общего со старым кодом.
DeveloperDon
OTOH, выравнивание данных по размеру строки кэша может оказать большое влияние. ;-p
Маке
3

Рассмотрим наиболее очевидный пример этого - «поиск пользовательских данных слишком медленный!»

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

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

Telastyn
источник
1

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

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

Есть замечательная книга (по крайней мере, когда она была опубликована) под названием: Алгоритмы + Структуры данных = Программы .

Без шансов
источник
0

Оптимизация кода может иногда повысить скорость в два раза, а иногда в десять или даже двадцать раз, но это все. Это может звучать как много, и если 75% времени выполнения программы тратится на подпрограмму из пяти строк, скорость которой можно легко удвоить, такая оптимизация вполне может стоить того. С другой стороны, выбор структур данных может влиять на скорость выполнения на многие порядки. Современный гипероптимизированный многопоточный процессор, выполняющий супероптимизированный код для поиска данных по ключу в линейном связанном списке из 10 000 000 элементов, хранящемся в ОЗУ, будет работать медленнее, чем гораздо более медленный процессор с довольно просто закодированной вложенной хэш-таблицей. Действительно, если бы данные были правильно изложены, даже 1980

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

Supercat
источник
0

Структуры данных влияют на производительность. Я думаю, что мы можем смотреть на проблемы усердно и долго с предвзятым представлением об идеальной структуре данных, и в этом контексте мышления даже создавать доказательства (часто по индукции) оптимальности. Например, если мы помещаем отсортированный список в массив и оцениваем такие вещи, как стоимость вставки элемента, мы можем в среднем решить, что нам нужно сдвигать 1/2 массива для каждой вставки. Для каждого двоичного поиска мы можем найти соответствующий элемент (или нет) в log n шагах.

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

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

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

DeveloperDon
источник
0

Чтобы сформулировать мое лучшее предположение о том, что означает эта статья, я предполагаю невысказанный подтекст (который, кажется, отсутствует в статье), который любой программист должен понимать об оптимизации:

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

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

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

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

comingstorm
источник
-1

Лучший программист: какая разница?

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

Дэвид Хаммен
источник