Алгоритмическая эффективность

Из Википедии, бесплатной энциклопедии

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

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

Например, пузырьковая сортировка и временная сортировка — это алгоритмы сортировки списка элементов от меньшего к большему. Пузырьковая сортировка сортирует список за время, пропорциональное количеству элементов в квадрате ( , см. обозначение Big O ), но требует лишь небольшого объема дополнительной памяти , которая постоянна относительно длины списка ( ). Timsort сортирует список линейно по времени (пропорционально количеству, умноженному на его логарифм) по длине списка ( ), но требует пространства, линейно зависящего от длины списка ( ). Если для данного приложения необходимо сортировать большие списки с высокой скоростью, лучшим выбором будет timsort; однако, если минимизация потребления памяти при сортировке более важна, лучшим выбором будет пузырьковая сортировка.

Предыстория [ править ]

Важность эффективности по отношению ко времени была подчеркнута Адой Лавлейс в 1843 году применительно к Чарльза Бэббиджа механической аналитической машине :

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

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

Современные компьютеры значительно быстрее, чем ранние компьютеры, и имеют гораздо больший объем доступной памяти ( гигабайты вместо килобайтов ). Тем не менее, Дональд Кнут подчеркнул, что эффективность по-прежнему является важным фактором:

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

Обзор [ править ]

Алгоритм считается эффективным, если его потребление ресурсов, также известное как вычислительные затраты, находится на некотором приемлемом уровне или ниже. Грубо говоря, «приемлемый» означает: он будет работать в течение разумного периода времени или пространства на доступном компьютере, обычно в зависимости от размера входных данных. С 1950-х годов в компьютерах произошел резкий рост как доступной вычислительной мощности, так и доступного объема памяти, поэтому текущие приемлемые уровни были бы неприемлемы даже 10 лет назад. Фактически, благодаря приблизительному удвоению мощности компьютеров каждые 2 года , задачи, которые приемлемо эффективны на современных смартфонах и встроенных системах, могли быть неприемлемо неэффективны для промышленных серверов 10 лет назад.

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

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

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

анализ Теоретический

При теоретическом анализе алгоритмов обычной практикой является оценка их сложности в асимптотическом смысле. Наиболее часто используемой нотацией для описания потребления ресурсов или «сложности» является Кнута Дональда нотация Big O , представляющая сложность алгоритма как функцию размера входных данных. . Обозначение Big O — это асимптотическая мера сложности функции, где грубо означает, что время, необходимое для алгоритма, пропорционально , опуская члены низшего порядка , вклад которых меньше к росту функции как вырастает сколь угодно большим . Эта оценка может ввести в заблуждение, если мала, но, как правило, достаточно точна, когда велико, поскольку обозначения асимптотические. Например, пузырьковая сортировка может быть быстрее сортировки слиянием , если необходимо отсортировать только несколько элементов; однако любая реализация, скорее всего, будет соответствовать требованиям к производительности для небольшого списка. Обычно программисты заинтересованы в алгоритмах, которые эффективно масштабируются для больших размеров входных данных, и сортировка слиянием предпочтительнее пузырьковой сортировки для списков длины, встречающихся в большинстве программ с интенсивным использованием данных.

Некоторые примеры нотации Big O, применяемой к асимптотической временной сложности алгоритмов, включают:

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

: производительности измерение Бенчмаркинг

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

Некоторые тесты предоставляют возможности для проведения анализа, сравнивающего относительную скорость различных компилируемых и интерпретируемых языков, например [3] [4] и The Computer Language Benchmarks Game сравнивает производительность реализаций типичных задач программирования на нескольких языках программирования.

Даже создание тестов « сделай сам » может продемонстрировать относительную производительность различных языков программирования, используя множество критериев, заданных пользователем. Это довольно просто, как показывает на примере «Обзор производительности девяти языков» Кристофера Коуэлла-Шаха. [5]

Проблемы реализации

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

Существуют и другие факторы, которые могут влиять на проблемы времени или пространства, но могут находиться вне контроля программиста; к ним относятся выравнивание данных , гранулярность данных , локальность кэша , согласованность кэша , сбор мусора , параллелизм на уровне инструкций , многопоточность (на аппаратном или программном уровне), одновременная многозадачность и вызовы подпрограмм . [7]

Некоторые процессоры имеют возможности векторной обработки , которые позволяют одной инструкции работать с несколькими операндами ; Программисту или компилятору может быть легко, а может и нелегко использовать эти возможности. Алгоритмы, разработанные для последовательной обработки, возможно, придется полностью перепроектировать для использования параллельной обработки , или их можно легко переконфигурировать. Поскольку в конце 2010-х годов важность параллельных и распределенных вычислений возрастает, все больше инвестиций делается в эффективные высокоуровневые API для параллельных и распределенных вычислительных систем, таких как CUDA , TensorFlow , Hadoop , OpenMP и MPI .

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

Меры использования ресурсов [ править ]

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

Двумя наиболее распространенными мерами являются:

  • Время : сколько времени занимает выполнение алгоритма?
  • Пространство : сколько оперативной памяти (обычно ОЗУ) необходимо алгоритму? Это имеет два аспекта: объем памяти, необходимый коду (использование вспомогательного пространства), и объем памяти, необходимый для данных, с которыми работает код (внутреннее использование пространства).

Для компьютеров, питание которых осуществляется от аккумулятора (например, ноутбуков и смартфонов ) или для очень длительных/больших вычислений (например, суперкомпьютеров ), представляют интерес другие меры:

  • Прямое энергопотребление : мощность, необходимая непосредственно для работы компьютера.
  • Косвенное энергопотребление : мощность, необходимая для охлаждения, освещения и т. д.

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

Менее распространенные меры вычислительной эффективности также могут быть актуальны в некоторых случаях:

  • Размер передачи : пропускная способность может быть ограничивающим фактором. Сжатие данных можно использовать для уменьшения объема передаваемых данных. Отображение изображения или изображения (например, логотипа Google ) может привести к передаче десятков тысяч байтов (в данном случае 48 КБ) по сравнению с передачей шести байтов для текста «Google». Это важно для вычислительных задач, связанных с вводом-выводом .
  • Внешнее пространство : необходимое пространство на диске или другом внешнем запоминающем устройстве; это может быть временное хранение во время выполнения алгоритма или долгосрочное хранение, необходимое для дальнейшего использования.
  • Время отклика ( задержка ): это особенно актуально в приложении реального времени , когда компьютерная система должна быстро реагировать на какое-то внешнее событие .
  • Общая стоимость владения : особенно, если компьютер предназначен для одного конкретного алгоритма.

Время [ править ]

Теория [ править ]

Проанализируйте алгоритм, обычно используя анализ временной сложности , чтобы получить оценку времени работы в зависимости от размера входных данных. Результат обычно выражается с использованием нотации Big O. Это полезно для сравнения алгоритмов, особенно когда необходимо обработать большой объем данных. Для сравнения производительности алгоритма при небольшом объеме данных необходимы более подробные оценки, хотя это, вероятно, будет иметь меньшее значение. Алгоритмы, включающие параллельную обработку, могут оказаться более трудными для анализа .

Практика [ править ]

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

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

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

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

Этот раздел посвящен использованию ресурсов памяти ( регистров , кэша , ОЗУ , виртуальной памяти , вторичной памяти ) во время выполнения алгоритма. Что касается анализа времени, описанного выше, анализируйте алгоритм, обычно используя анализ пространственной сложности , чтобы получить оценку необходимой оперативной памяти в зависимости от размера входных данных. Результат обычно выражается с использованием нотации Big O.

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

Ранние электронные компьютеры и первые домашние компьютеры имели относительно небольшой объем рабочей памяти. Например, автоматический калькулятор с электронным запоминанием задержки (EDSAC) 1949 года имел максимальную рабочую память в 1024 17-битных слов, а Sinclair ZX80 1980 года изначально имел 1024 8-битных байта рабочей памяти. характерно В конце 2010-х годов для персональных компьютеров иметь от 4 до 32 ГБ оперативной памяти, что более чем в 300 миллионов раз больше памяти.

Иерархия кэширования и памяти [ править ]

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

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

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

См. также [ править ]

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

  1. ^ Грин, Кристофер, Классика по истории психологии , получено 19 мая 2013 г.
  2. ^ Кнут, Дональд (1974), «Структурное программирование с операторами перехода» (PDF) , Computing Surveys , 6 (4): 261–301, CiteSeerX   10.1.1.103.6084 , doi : 10.1145/356635.356640 , S2CID   207630080 , заархивировано из оригинал (PDF) 24 августа 2009 г. , получено 19 мая 2013 г.
  3. ^ Перейти обратно: а б «Бенчмарк с плавающей запятой: сравнение языков (Fourmilog: никто не смеет называть это разумом)» . Fourmilab.ch. 4 августа 2005 г. Проверено 14 декабря 2011 г.
  4. ^ «История точильного теста» . Ройлонгботтом.org.uk . Проверено 14 декабря 2011 г.
  5. ^ Сотрудники OSNews. «Обзор производительности девяти языков: сравнительный анализ математических вычислений и файлового ввода-вывода» . osnews.com . Проверено 18 сентября 2018 г.
  6. ^ Кригель, Ханс-Петер ; Шуберт, Эрих; Зимек, Артур (2016). «(Черное) искусство оценки времени выполнения: сравниваем ли мы алгоритмы или реализации?». Знания и информационные системы . 52 (2): 341–378. дои : 10.1007/s10115-016-1004-2 . ISSN   0219-1377 . S2CID   40772241 .
  7. ^ Гай Льюис Стил-младший «Разоблачение мифа о« дорогом вызове процедур », или Реализация вызова процедур считается вредной, или Лямбда: окончательный GOTO». Лаборатория искусственного интеллекта Массачусетского технологического института. Памятка лаборатории искусственного интеллекта AIM-443. Октябрь 1977 г. [1]
  8. ^ Перейти обратно: а б с д Хеннесси, Джон Л; Паттерсон, Дэвид А; Асанович, Крсте ; Бакос, Джейсон Д; Колвелл, Роберт П.; Бхаттачарджи, Абхишек; Конте, Томас М; Дуато, Хосе; Франклин, Диана; Гольдберг, Дэвид; Жуппи, Норман П ; Ли, Шэн; Муралиманохар, Навин; Петерсон, Грегори Д.; Пинкстон, Тимоти Марк; Ранганатан, Пракаш; Вуд, Дэвид Аллен; Янг, Клиффорд; Заки, Амр (2011). Компьютерная архитектура: количественный подход (Шестое изд.). Эльзевир Наука. ISBN  978-0128119051 . OCLC   983459758 .