Все говорят, что я должен сделать свой код модульным, но разве это не менее эффективно, если я использую больше вызовов методов, а не меньше, но больше методов? Какая разница в Java, C или C ++ в этом отношении?
Я понимаю, что легче редактировать, читать и понимать, особенно в группе. Таким образом, потери времени вычислений незначительны по сравнению с преимуществами аккуратности кода?
java
c++
c
efficiency
fatsokol
источник
источник
Ответы:
Да, это не имеет значения.
Компьютеры - это неутомимые двигатели почти идеального исполнения, работающие на скоростях, совершенно несопоставимых с мозгом. Хотя есть измеримое количество времени, которое вызов функции добавляет ко времени выполнения программы, это ничто по сравнению с дополнительным временем, необходимым мозгу следующего человека, связанного с кодом, когда им приходится распутывать нечитаемую подпрограмму. даже начать понимать, как с этим работать. Вы можете попробовать вычисления в шутку - предположим, что ваш код должен поддерживаться только один раз , и это только добавляет полчаса к времени, необходимому для того, чтобы кто-то смирился с кодом. Возьмите тактовую частоту вашего процессора и посчитайте: сколько раз придется запускать код, чтобы хотя бы мечтать о его компенсации?
Короче говоря, в 99,99% случаев жалость к процессору совершенно ошибочна. В редких оставшихся случаях используйте профилировщики. Вы не предполагает , что вы можете определить те случаи , - вы не можете.
источник
По-разному.
В ледяном медленном мире, где есть веб-программирование, где все происходит с человеческой скоростью, программирование с интенсивным использованием методов, где стоимость вызова метода сопоставима или превышает стоимость обработки, выполняемой этим методом, вероятно, не имеет значения ,
В мире программирования встроенных систем и обработчиков прерываний для высокоскоростных прерываний это, безусловно, имеет значение. В этой среде обычные модели «доступ к памяти дешев» и «процессор бесконечно быстр» выходят из строя. Я видел, что происходит, когда объектно-ориентированный программист мэйнфрейма пишет свой первый высокоскоростной обработчик прерываний. Это было не красиво.
Несколько лет назад я выполнял нерекурсивную 8-полосную раскраску блогов для подключения к изображениям FLIR в реальном времени на том, что в то время было достойным процессором. Первая попытка использовала вызов подпрограммы, и издержки вызова подпрограммы сожрали процессор. (4 вызова на ПИКСЕЛ x 64K пикселей на кадр x 30 кадров в секунду = вы выясните это). Вторая попытка превратила подпрограмму в макрос C без потери читаемости, и все было розами.
Вы должны смотреть ТРУДНО на то, что вы делаете, и на среду, в которой вы будете это делать.
источник
Прежде всего: программы на более высоком языке предназначены для чтения людьми, а не машинами.
Так что пишите программы, чтобы вы их понимали. Не думайте о производительности (если у вас есть серьезные проблемы с производительностью, профилируйте ваше приложение и повышайте производительность там, где это необходимо).
Даже если это правда, что вызов метода или функции требует дополнительных затрат, это не имеет значения. Сегодня компиляторы должны иметь возможность компилировать ваш код на эффективный машинный язык, чтобы сгенерированный код был эффективным для целевой архитектуры. Используйте переключатели оптимизации вашего компилятора, чтобы получить эффективный код.
источник
Обычно, когда у вас есть большая функция, и вы разбиваете ее на множество меньших, эти меньшие будут встроены, потому что единственная обратная сторона встраивания (слишком много повторяющихся инструкций) в этом случае не имеет значения. Это означает, что ваш код будет действовать так, как если бы вы написали одну большую функцию.
Если они по какой-то причине не встроены, и это становится проблемой производительности, то вам следует рассмотреть возможность ручной вставки. Не все приложения являются сетевыми формами CRUD с огромными внутренними задержками.
источник
Вероятно, нет затрат на вычисления. Обычно компиляторы / JIT за последние 10-20 лет или около того прекрасно справляются с функцией встраивания. Для C / C ++ обычно это ограничивается «встроенными» функциями (т.е. определение функции доступно для компилятора во время компиляции - то есть оно находится в заголовке того же файла), но современные методы LTO преодолевают это.
Если вы должны потратить время на оптимизацию, зависит от области, над которой вы работаете. Если вы имеете дело с «обычным» приложением, которое большую часть времени ждали ввода - возможно, вам не следует беспокоиться об оптимизации, если приложение не чувствует себя медленным.
Даже в таких случаях вы должны сосредоточиться на многих вещах, прежде чем выполнять микрооптимизацию:
O(n)
наO(log n)
может оказать гораздо большее влияние, чем все, что вы могли бы достичь с помощью микрооптимизации.List
когда вам нужно,HashSet
чтобы у вас былO(n)
поиск, когда вы могли бы иметьO(1)
.Даже если вы решите, что вам необходимо выполнить микрооптимизацию (что фактически означает, что ваше программное обеспечение используется в HPC, встроено или просто используется очень большим количеством людей - в противном случае дополнительные затраты на обслуживание превышают затраты времени компьютера), вам нужно чтобы определить горячие точки (ядра), которые вы хотите ускорить. Но тогда вы, вероятно, должны:
В качестве последнего замечания. Обычно единственная проблема, с которой вы сталкиваетесь при вызове методов, - это косвенные переходы (виртуальные методы), которые не были предсказаны предсказателем ветвлений (к сожалению, непростой переход - трудный случай для этого). Тем не мение:
источник
Мой ответ, вероятно, не слишком расширит существующие ответы, но я чувствую, что мои два цента могут быть полезны.
Прежде всего; да, для модульности вы обычно отказываетесь от некоторого уровня времени выполнения. Написание всего на ассемблере даст вам лучшую скорость. Это сказал ...
Вы знаете YouTube? Скорее всего, это сайт с самой высокой пропускной способностью или второй после Netflix? Они пишут большую часть своего кода на Python, который является высокомодульным языком, не совсем созданным для первоклассной производительности.
Дело в том, что когда что-то идет не так, и пользователи жалуются на медленную загрузку видео, существует не так много сценариев, в которых эта медлительность в конечном итоге объясняется медленной скоростью выполнения Python. Однако быстрая перекомпиляция Python и его модульная возможность пробовать новые вещи без проверки типов, вероятно, позволят инженерам довольно быстро отладить то, что идет не так («Вау. Наш новый стажер написал цикл, который выполняет новый подзапрос SQL для КАЖДОГО результата. ") или (" О, Firefox устарел, этот старый формат кэширования заголовка; и они создали библиотеку Python для легкой установки нового ")
В этом смысле, даже с точки зрения времени выполнения, модульный язык можно считать более быстрым, потому что, как только вы обнаружите свои узкие места, вам, вероятно, станет легче реорганизовать код, чтобы он работал наилучшим образом. Так много инженеров скажут вам, что хиты с высокой производительностью были не там, где они думали, что будут (и на самом деле то, что они ДЕЙСТВИТЕЛЬНО оптимизировали, вряд ли было нужно, или даже не работало так, как они ожидали!)
источник
Да и нет. Как и другие отметили программу сначала для удобочитаемости, а затем для эффективности. Тем не менее, существуют стандартные практики, которые читабельны и эффективны. Большая часть кода запускается довольно редко, и вы все равно не получите большого преимущества от его оптимизации.
Java может встроить меньшие вызовы функций, поэтому нет особых причин избегать написания функций. Оптимизаторы, как правило, работают лучше с более простым и легким для чтения кодом. Есть исследования, которые показывают, что ярлыки, которые теоретически должны работать быстрее, на самом деле занимают больше времени. JIT-компилятор, вероятно, будет работать лучше, код меньше, и часто выполняемые части могут быть идентифицированы и оптимизированы. Я не пробовал, но я ожидал, что одна большая функция, которая относительно редко вызывается, не будет скомпилирована.
Это, вероятно, не относится к Java, но одно исследование показало, что большие функции на самом деле работают медленнее из-за необходимости использования другой эталонной модели памяти. Это было специфично для оборудования и оптимизатора. Для небольших модулей были использованы инструкции, которые работали на странице памяти. Они были быстрее и меньше, чем инструкции, необходимые, когда функция не подходила под страницу.
Есть случаи, когда стоит оптимизировать код, но обычно вам нужно профилировать код, чтобы определить, где он находится. Я нахожу, что это часто не тот код, который я ожидал.
источник