~~~~~~~~~~~~~~~~~~~~ Arc.Ask3.Ru ~~~~~~~~~~~~~~~~~~~~~ 
Номер скриншота №:
✰ B1D403EFB6FBA5E947A5A1EB7FE4807F__1706548560 ✰
Заголовок документа оригинал.:
✰ Program optimization - Wikipedia ✰
Заголовок документа перевод.:
✰ Оптимизация программы — Википедия ✰
Снимок документа находящегося по адресу (URL):
✰ https://en.wikipedia.org/wiki/Code_optimization ✰
Адрес хранения снимка оригинал (URL):
✰ https://arc.ask3.ru/arc/aa/b1/7f/b1d403efb6fba5e947a5a1eb7fe4807f.html ✰
Адрес хранения снимка перевод (URL):
✰ https://arc.ask3.ru/arc/aa/b1/7f/b1d403efb6fba5e947a5a1eb7fe4807f__translat.html ✰
Дата и время сохранения документа:
✰ 21.06.2024 10:26:16 (GMT+3, MSK) ✰
Дата и время изменения документа (по данным источника):
✰ 29 January 2024, at 20:16 (UTC). ✰ 

~~~~~~~~~~~~~~~~~~~~~~ Ask3.Ru ~~~~~~~~~~~~~~~~~~~~~~ 
Сервисы Ask3.ru: 
 Архив документов (Снимки документов, в формате HTML, PDF, PNG - подписанные ЭЦП, доказывающие существование документа в момент подписи. Перевод сохраненных документов на русский язык.)https://arc.ask3.ruОтветы на вопросы (Сервис ответов на вопросы, в основном, научной направленности)https://ask3.ru/answer2questionТоварный сопоставитель (Сервис сравнения и выбора товаров) ✰✰
✰ https://ask3.ru/product2collationПартнерыhttps://comrades.ask3.ru


Совет. Чтобы искать на странице, нажмите Ctrl+F или ⌘-F (для MacOS) и введите запрос в поле поиска.
Arc.Ask3.ru: далее начало оригинального документа

Оптимизация программы — Википедия Jump to content

Оптимизация программы

Из Википедии, бесплатной энциклопедии
(Перенаправлено из Оптимизация кода )

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

Общие [ править ]

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

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

Уровни оптимизации [ править ]

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

Поскольку производительность является частью спецификации программы, программа, которая неприемлемо медленна, не подходит для этой цели: видеоигра с частотой 60 Гц (кадров в секунду) приемлема, но 6 кадров в секунду неприемлемо прерывисты. Производительность учитывается с самого начала, чтобы гарантировать, что система способна обеспечить достаточную производительность, а ранние прототипы должны иметь примерно приемлемую производительность, чтобы была уверенность в том, что конечная система (с оптимизацией) достигнет приемлемой производительности. Иногда об этом забывают, полагая, что оптимизацию всегда можно провести позже, в результате чего прототипы систем работают слишком медленно (часто на порядок и более) и системы, которые в конечном итоге терпят неудачу, потому что они архитектурно не могут достичь своих целей по производительности, например как Intel 432 (1981 г.); или те, которые требуют многих лет работы для достижения приемлемой производительности, например Java (1995), которая достигла приемлемой производительности только с помощью HotSpot (1999). Степень изменения производительности между прототипом и производственной системой и то, насколько она поддается оптимизации, может быть существенным источником неопределенности и риска.

Уровень дизайна [ править ]

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

Алгоритмы и структуры данных [ править ]

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

Для алгоритмов это в первую очередь состоит в обеспечении того, чтобы алгоритмы были постоянными O(1), логарифмическими O(log n ), линейными O( n ) или, в некоторых случаях, лог-линейными O( n log n ) на входе (оба в пространстве и время). Алгоритмы квадратичной сложности O( n 2 ) не масштабируются, и даже линейные алгоритмы вызывают проблемы при неоднократном вызове и обычно заменяются константными или логарифмическими, если это возможно.

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

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

Уровень исходного кода [ править ]

Помимо общих алгоритмов и их реализации на абстрактной машине, выбор конкретного уровня исходного кода может иметь существенное значение. Например, в ранних компиляторах C while(1) был медленнее, чем for(;;) для безусловного цикла, потому что while(1) вычислил 1, а затем выполнил условный переход, который проверял, истинно ли это, в то время как for (;;)был безусловный прыжок. Некоторые оптимизации (например, эта) в настоящее время могут быть выполнены путем оптимизации компиляторов . Это зависит от исходного языка, целевого машинного языка и компилятора и может быть трудным для понимания или прогнозирования и может меняться со временем; это ключевой момент, где понимание компиляторов и машинного кода может повысить производительность. Инвариантное к циклу движение кода и оптимизация возвращаемого значения являются примерами оптимизаций, которые уменьшают потребность во вспомогательных переменных и могут даже привести к повышению производительности за счет исключения обходных оптимизаций.

Уровень сборки [ править ]

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

Уровень компиляции [ править ]

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

Уровень сборки [ править ]

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

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

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

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

Время выполнения [ править ]

Компиляторы «точно в срок» могут создавать индивидуальный машинный код на основе данных времени выполнения за счет накладных расходов на компиляцию. Этот метод восходит к самым ранним механизмам регулярных выражений и получил широкое распространение благодаря Java HotSpot и V8 для JavaScript. В некоторых случаях адаптивная оптимизация может обеспечить оптимизацию времени выполнения , превосходящую возможности статических компиляторов, путем динамической настройки параметров в соответствии с фактическими входными данными или другими факторами.

Оптимизация на основе профиля — это метод оптимизации компиляции с опережением времени (AOT), основанный на профилях времени выполнения и похожий на статический аналог динамического метода адаптивной оптимизации в «среднем случае».

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

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

Платформозависимые и независимые оптимизации [ править ]

Оптимизацию кода также можно разделить на платформо -зависимые и платформо-независимые методы. Хотя последние эффективны на большинстве или всех платформах, платформо-зависимые методы используют определенные свойства одной платформы или полагаются на параметры, зависящие от одной платформы или даже от одного процессора. Поэтому может потребоваться написание или создание разных версий одного и того же кода для разных процессоров. Например, в случае оптимизации на уровне компиляции независимые от платформы методы являются общими методами (такими как развертывание цикла , сокращение вызовов функций, процедуры с эффективным использованием памяти, сокращение условий и т. д.), которые одинаково влияют на большинство архитектур ЦП. способ. Отличный пример независимой от платформы оптимизации был показан с помощью внутреннего цикла for: было замечено, что цикл с внутренним циклом for выполняет больше вычислений в единицу времени, чем цикл без него или цикл с внутренним циклом while. [2] Как правило, они служат для уменьшения общей длины пути инструкции , необходимой для завершения программы, и/или уменьшения общего использования памяти во время процесса. С другой стороны, платформо-зависимые методы включают планирование инструкций, параллелизм на уровне инструкций , параллелизм на уровне данных, методы оптимизации кэша (т. е. параметры, которые различаются на разных платформах), а оптимальное планирование инструкций может быть разным даже на разных процессорах. та же архитектура.

Снижение силы [ править ]

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

int   я  ,   сумма   =   0  ; 
  для   (  я   знак равно   1  ;   я   <=   N  ;   ++  я  )   { 
   сумма   +=   я  ; 
  } 
 printf  (  "сумма: %d  \n  "  ,   сумма  ); 

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

int   сумма   =   N   *   (  1   +   N  )   /   2  ; 
  printf  (  "сумма: %d  \n  "  ,   сумма  ); 

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

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

Компромиссы [ править ]

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

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

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

Узкие места [ править ]

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

В информатике потребление ресурсов часто подчиняется степенному закону распределения, и принцип Парето можно применить к оптимизации ресурсов, заметив, что 80% ресурсов обычно используются в 20% операций. [3] В разработке программного обеспечения часто лучшим приближением является то, что 90% времени выполнения компьютерной программы тратится на выполнение 10% кода (в этом контексте это известно как закон 90/10).

Более сложные алгоритмы и структуры данных хорошо работают со многими элементами, в то время как простые алгоритмы больше подходят для небольших объемов данных — настройка, время инициализации и постоянные факторы более сложного алгоритма могут перевесить выгоду, и, следовательно, гибридный алгоритм или адаптивный Алгоритм может быть быстрее, чем любой отдельный алгоритм. Профилировщик производительности можно использовать для сужения решений о том, какая функциональность соответствует каким условиям. [4]

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

Когда оптимизировать [ править ]

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

Дональд Кнут сделал следующие два заявления по поводу оптимизации:

«Мы должны забыть о небольшой эффективности, скажем, о 97% времени: преждевременная оптимизация — это корень всех зол. Однако мы не должны упускать наши возможности в этих критических 3%» [5]

он также приписал эту цитату Тони Хоару : ( Несколько лет спустя [6] хотя это могло быть ошибкой, поскольку Хоар отрицает, что придумал эту фразу. [7] )

«В устоявшихся инженерных дисциплинах легко достижимое улучшение на 12% никогда не считается незначительным, и я считаю, что такая же точка зрения должна преобладать в разработке программного обеспечения». [5]

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

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

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

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

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

Макросы [ править ]

Оптимизация при разработке кода с использованием макросов принимает разные формы на разных языках.

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

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

Лисп создал этот стиль макросов, [ нужна цитата ] и такие макросы часто называют «lisp-подобными макросами». Аналогичного эффекта можно добиться, используя метапрограммирование шаблонов в C++ .

В обоих случаях работа переносится на время компиляции. Разница между макросами C , с одной стороны, и макросами, подобными Lisp, и C++ метапрограммированием шаблонов , с другой, заключается в том, что последние инструменты позволяют выполнять произвольные вычисления во время компиляции/анализа, в то время как расширение макросов C не выполняет никаких действий. вычислений и полагается на способность оптимизатора выполнить их. Кроме того, макросы C не поддерживают напрямую рекурсию или итерацию , поэтому не являются полными по Тьюрингу .

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

Автоматическая и ручная оптимизация [ править ]

См. также Категория:Оптимизация компилятора.

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

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

Используйте профилировщик (или анализатор производительности ), чтобы найти разделы программы, которые забирают больше всего ресурсов — узкое место . Программисты иногда полагают, что имеют четкое представление о том, где находится узкое место, но интуиция часто ошибается. [ нужна цитата ] Оптимизация неважного фрагмента кода обычно мало что дает для повышения общей производительности.

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

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

Узкие места производительности могут быть связаны с ограничениями языка, а не с алгоритмами или структурами данных, используемыми в программе. Иногда критически важную часть программы можно переписать на другом языке программирования , который обеспечивает более прямой доступ к базовой машине. Например, для очень высокого уровня, языков таких как Python, модули написаны на C. для большей скорости Программы, уже написанные на C, могут иметь модули, написанные на ассемблере . Программы, написанные на D, могут использовать встроенный ассемблер .

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

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

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

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

Некоторые языки высокого уровня ( Eiffel , Esterel ) оптимизируют свои программы, используя промежуточный язык .

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

Время, затраченное на оптимизацию [ править ]

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

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

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

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

Ссылки [ править ]

  1. ^ Роберт Седжвик , Алгоритмы , 1984, с. 84.
  2. ^ Адевуми, Тосин П. (01 августа 2018 г.). «Конструкция программы внутреннего цикла: более быстрый способ выполнения программы» . Открытая информатика . 8 (1): 115–122. дои : 10.1515/comp-2018-0004 .
  3. ^ Уэскотт, Боб (2013). Книга о производительности каждого компьютера, глава 3: Полезные законы . Создать пространство . ISBN  978-1482657753 .
  4. ^ «Профилирование производительности с фокусом» . Проверено 15 августа 2017 г.
  5. ^ Перейти обратно: а б Кнут, Дональд (декабрь 1974 г.). «Структурное программирование с переходом к операторам». Обзоры вычислительной техники ACM . 6 (4): 268. CiteSeerX   10.1.1.103.6084 . дои : 10.1145/356635.356640 . S2CID   207630080 .
  6. ^ Ошибки TeX , в журнале «Программное обеспечение — практика и опыт» , том 19, выпуск 7 (июль 1989 г.), стр. 607–685, перепечатано в его книге «Грамотное программирование» (стр. 276).
  7. ^ «Преждевременная оптимизация — корень всех зол» . hans.gerwitz.com . Проверено 18 декабря 2020 г. Хоар, однако, не утверждал этого, когда я спрашивал его в январе 2004 года.
  8. ^ Мемети, Суэйб; Планана, Сабри; Бинотто, Алесио; Колодзей, Иоанна; Брандич, Ивона (26 апреля 2018 г.). «Использование метаэвристики и машинного обучения для оптимизации программного обеспечения параллельных вычислительных систем: систематический обзор литературы». Вычисление . 101 (8). Спрингер Вена: 893–936. arXiv : 1801.09444 . Бибкод : 2018arXiv180109444M . дои : 10.1007/s00607-018-0614-9 . S2CID   13868111 .

Дальнейшее чтение [ править ]

Arc.Ask3.Ru: конец оригинального документа.
Arc.Ask3.Ru
Номер скриншота №: B1D403EFB6FBA5E947A5A1EB7FE4807F__1706548560
URL1:https://en.wikipedia.org/wiki/Code_optimization
Заголовок, (Title) документа по адресу, URL1:
Program optimization - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть, любые претензии не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, денежную единицу можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)