Следует ли разработчику в первую очередь стремиться к удобочитаемости или производительности? [закрыто]


82

Часто разработчик сталкивается с выбором между двумя возможными способами решения проблемы - одним, который является идиоматическим и удобочитаемым, и другим, менее интуитивно понятным, но может работать лучше. Например, в языках на основе C есть два способа умножить число на 2:

int SimpleMultiplyBy2(int x)
{
    return x * 2; 
}

и

int FastMultiplyBy2(int x)
{
    return x << 1;
}

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

Как разработчик, что было бы лучше в качестве первой попытки?


Немного сурово. Хороший вопрос о том, что время от времени у всех нас возникает. +1
Инишир

3
Этот пример явно надуманный и тривиальный. У вас не было бы функции с жестко запрограммированным множителем.
JohnMcG

1
Дело в том, что я вижу много вопросов вроде "работает ли <лучше, чем <=?" Это неправильный вопрос - правильный (первый) вопрос - что является идиоматическим или условным, а затем беспокоиться о производительности.
JohnMcG

1
Это один из лучших вопросов, которые я читал о stackoverflow. Это касается сути работы компьютеров, а не только семантики языка. +1
WolfmanDragon

2
@OutlawLemur Я в курсе. Но некоторые люди спрашивают, не лучше ли, например, строить циклы с помощью <или <= (в последнем случае значение для сравнения увеличивается заранее).
JohnMcG

Ответы:


109

Вы пропустили один.

Сначала код для правильности, затем для ясности (эти два понятия, конечно, часто связаны!). Наконец, и только если у вас есть реальные эмпирические доказательства, которые вам действительно нужны, вы можете заняться оптимизацией. Преждевременная оптимизация - это действительно зло. Оптимизация почти всегда требует времени, ясности и удобства обслуживания. Вам лучше убедиться, что вы покупаете что-то стоящее на это.

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


Это, безусловно, лучший ответ. Изменяйте алгоритм, а не код. С небольшими изменениями я могу заставить jscript Sieve of Erastosthenes превзойти по производительности идентичную в остальном версию C ++. (Не решето Аткинса, мой собственный метод.)
Питер Вон,

2
Жаль, что нельзя добавлять ответы в избранное. :)
Шандор Давидхази

59

ИМО сначала очевидная читаемая версия, пока не будет измерена производительность и не потребуется более быстрая версия.


Я согласен. В прошлом году я реализовал важный компонент, помимо серверной базы кода Java моей компании, и приложил все усилия, чтобы сделать его читабельным. Позже выяснилось, что были проблемы с производительностью, и была проведена серьезная переработка его дизайна, что привело к тому, что в некоторых отношениях стало немного менее читабельным.
Райан Делукки,

46

Возьми это из Дона Кнута

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


Цитата не от самого Дона, а от Хора. Дон просто сделал это популярным. Проверьте википедию.
Колерм

1
И это выборочная цитата одного пункта из целого абзаца, который содержит некоторые очень важные оговорки.
user207421

19

Читаемость 100%

Если ваш компилятор не может выполнить оптимизацию "x * 2" => "x << 1" за вас - приобретите новый компилятор!

Также помните, что 99,9% времени вашей программы тратится на ожидание ввода пользователя, ожидание запросов к базе данных и ожидание ответов сети. Если вы не проделаете несколько 20 миллиардов раз, это не будет заметно.


8

В данном примере 99,9999% компиляторов будут генерировать один и тот же код для обоих случаев. Это иллюстрирует мое общее правило - сначала пишите для удобства чтения и поддержки, а оптимизируйте только тогда, когда вам нужно.


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

Для этого конкретного примера, конечно. Есть много случаев, когда это не так, поэтому общий вопрос все еще остается хорошим
Марк Бейкер

@WolfmanDragon, о чем ты, черт возьми? Почему «* 2» генерирует цикл? Когда я пробую это с "gcc -O2 -s", я получаю инструкции addl в обоих случаях.
Пол Томблин

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

8

Читаемость точно. Не беспокойтесь о скорости, если кто-то не пожалуется


8

Читаемость.

У кодирования для повышения производительности есть свой набор проблем. Джозеф М. Ньюкомер сказал это хорошо

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

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


5

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


5

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

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


4

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


4

Поместив комментарий с объяснением, вы сделаете его читабельным и быстрым.

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


3

Ответ зависит от контекста. Например, при программировании драйверов устройств или разработке игр вторая форма является приемлемой идиомой. В бизнес-приложениях не так уж и много.

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


3

использование << было бы микрооптимизацией. Итак, правило Хора (не Кнатса):

Преждевременная оптимизация - это корень всех зол.

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

Это правило, ИМХО, часто используется как предлог для разработки программного обеспечения, которое никогда не масштабируется или не работает хорошо.


3

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

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

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


2

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


2

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


2

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

Сказав это, вы всегда можете оставить комментарии там, где удобное кодирование требует пояснения.


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

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

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

2

Я не работаю в Google, поэтому я бы выбрал злой вариант. (оптимизация)

В главе 6 книги Джона Бентли «Жемчужины программирования» он описывает, как одна система увеличила скорость в 400 раз за счет оптимизации на 6 различных уровнях проектирования. Я считаю, что, не заботясь о производительности на этих 6 уровнях проектирования, современные разработчики могут легко добиться снижения производительности своих программ на 2-3 порядка.


1

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

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

Но оптимизацией типа n << C обычно пренебречь, и ее тривиально изменить в любой момент. Сделать код читабельным - нет.


1

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


1

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


1

По оценкам, около 70% стоимости программного обеспечения приходится на обслуживание. Читаемость упрощает обслуживание системы и, следовательно, снижает стоимость программного обеспечения на протяжении всего срока ее службы.

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

Прежде чем жертвовать удобочитаемостью, подумайте: «Готов ли я (или ваша компания) справиться с дополнительными затратами, которые я добавляю системе, делая это?»


1

Как почти все сказали в своих ответах, я за удобочитаемость . В 99 из 100 проектов, которые я выполняю, нет жестких требований к времени отклика, так что это простой выбор.

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

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


1

Читаемость - ПЕРВАЯ цель.

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

ЕДИНСТВЕННЫЙ метод, который имел статистически значимое значение в развитии, был ...

ДОБАВЛЕНИЕ ПУСТОЙ СТРОК в программный код.

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

==============

Оптимизацией следует заниматься только тогда, когда весь проект проходит модульное тестирование и готов к использованию. Никогда не знаешь ГДЕ нужно оптимизировать код.

В своих знаковых книгах Керниган и Плаугер в конце 1970-х годов SOFTWARE TOOLS (1976) и SOFTWARE TOOLS IN PASCAL (1981) показали способы создания структурированных программ с использованием проектирования сверху вниз. Они создали программы обработки текста: редакторы, инструменты поиска, препроцессоры кода.

Когда завершенная функция форматирования текста была ИНСТРУМЕНТОВАНА, они обнаружили, что большая часть времени обработки была потрачена на три процедуры, которые выполняли ввод и вывод текста (в исходной книге функции io занимали 89% времени. В книге Паскаля эти функции израсходовано 55%!)

Они смогли оптимизировать эти ТРИ процедуры и добиться повышения производительности при разумных, контролируемых сроках разработки и затратах.


1

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

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

Проверь это


1

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

Производительность следует улучшать только тогда, когда это проблема в вашей программе, есть много мест, которые могут быть узким местом, а не этот синтаксис. Допустим, вы увеличиваете 1 нс по сравнению с <<, но игнорируете эти 10 минут ввода-вывода.

Кроме того, что касается удобочитаемости, профессиональный программист должен уметь читать / понимать термины информатики. Например, мы можем назвать метод enqueue вместо того, чтобы говорить putThisJobInWorkQueue.


Хотя я согласен, я думаю, что у вас плохой пример. Например, как человек, который ничего не знает о вашей кодовой базе, enqueue для меня меньше значит. Я не хочу знать как, я хочу знать что. Приведенный вами пример говорит о том, что намного лучше.
Шон Свит,

0

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

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


0

Я бы посоветовал пойти на читабельность

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

Если бы у нас всегда были функции, которые говорили нам, что они делают ...


0

Сколько стоит час процессорного времени?

Сколько стоит час рабочего времени программиста?


1
сколько стоит час рабочего времени конечного пользователя? теперь умножьте это на количество пользователей.
gbjbaanb

gbjbaanb: Мои мысли в точности. Комментарий Энди работает только для услуг, которые конечный пользователь никогда не увидит, и даже в этом случае это вряд ли хорошее сравнение.
Эрик ван Бракель,

0

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.