Эффективность алгоритмаЭффективность алгоритма — это свойство алгоритма, которое связано с вычислительными ресурсами, используемыми алгоритмом. Алгоритм должен быть проанализирован с целью определения необходимых алгоритму ресурсов. Эффективность алгоритма можно рассматривать как аналог производственной производительности повторяющихся или непрерывных процессов. Для достижения максимальной эффективности мы желаем уменьшить использование ресурсов. Однако различные ресурсы (такие как время и память) нельзя сравнить напрямую, так что какой из двух алгоритмов считать более эффективным часто зависит от того, какой фактор более важен, например, требование высокой скорости, минимального использования памяти или другой меры эффективности.
История вопросаВажность эффективности с упором на время исполнения подчёркивала Ада Лавлейс в 1843 по поводу механической аналитической машины Чарлза Бэббиджа:
Ранние электронные компьютеры были очень ограничены как по скорости, так и по памяти. В некоторых случаях было осознано, что существует компромисс времени и памяти, при котором задача должна либо использовать большое количество памяти для достижения высокой скорости, либо использовать более медленный алгоритм, использующий небольшое количество рабочей памяти. В этом случае использовался наиболее быстрый алгоритм, для которого было достаточно имеющейся памяти. Современные компьютеры намного быстрее тех ранних компьютеров и имеют много больше памяти (гигабайты вместо килобайт). Тем не менее, Дональд Кнут подчёркивает, что эффективность остаётся важным фактором:
ОбзорАлгоритм считается эффективным, если потребляемый им ресурс (или стоимость ресурса) на уровне или ниже некоторого приемлемого уровня. Грубо говоря, «приемлемый» здесь означает «алгоритм будет работать умеренное время на доступном компьютере». Поскольку с 1950-х годов наблюдалось значительное увеличение вычислительной мощности и доступной памяти компьютеров, существующий «приемлемый уровень» не был приемлемым даже 10 лет назад. Производители компьютеров периодично выпускают новые модели, зачастую более мощные. Стоимость программного обеспечения может быть достаточно велика, так что в некоторых случаях проще и дешевле для достижения лучшей производительности купить более быстрый компьютер, обеспечивающий совместимость с существующим компьютером. Существует много путей измерения используемых алгоритмом ресурсов. Два наиболее используемых измерения — скорость и используемая память. Другие измерения могут включать скорость передачи, временное использование диска, долговременное использование диска, потребление энергии, совокупная стоимость владения, время отклика на внешние сигналы и так далее. Многие из этих измерений зависят от размера входных данных алгоритма (то есть от количеств, требующих обработки данных). Измерения могут также зависеть от способа, в котором данные представлены (например, некоторые алгоритмы сортировки плохо работают на уже сортированных данных или когда данные отсортированы в обратном порядке). На практике существуют и другие факторы, влияющие на эффективность алгоритма, такие как требуемая точность и/или надёжность. Как объяснено ниже, способ реализации алгоритма может также дать существенный эффект на фактическую эффективность, хотя многие аспекты реализации относятся к вопросам оптимизации. Теоретический анализВ теоретическом анализе алгоритмов обычной практикой является оценка сложности алгоритма в его асимптотическом поведении, то есть для отражения сложности алгоритма как функции от размера входа n используется нотация «O» большое. Эта оценка, в основном, достаточно точна при большом n, но может привести к неправильным выводам при малых значениях n (так, сортировка пузырьком, считающаяся медленной, может оказаться быстрее «быстрой сортировки», если нужно отсортировать лишь несколько элементов). Некоторые примеры нотации «O» большое:
Проверочные испытания: измерение производительностиДля новых версий программного обеспечения или для обеспечения сравнения с соперничающими системами иногда используются тесты, позволяющие сравнить относительную производительность алгоритмов. Если, например, выпускается новый алгоритм сортировки, его можно сравнить с предшественниками, чтобы убедиться, что алгоритм по меньшей мере столь же эффективен на известных данных, как и другие. Тесты производительности могут быть использованы пользователями для сравнения продуктов от различных производителей для оценки, какой продукт будет больше подходить под их требования в терминах функциональности и производительности. Некоторые тесты производительности дают возможность проведения сравнительного анализа различных компилирующих и интерпретирующих языков, как, например, Roy Longbottom’s PC Benchmark Collection[3], а The Computer Language Benchmarks Game[англ.] сравнивает производительность реализаций типичных задач в некоторых языках программирования. (Достаточно легко создать «самодельные» тесты производительности для получения представления об относительной эффективности различных языков программирования, используя набор пользовательских критериев, как это сделал Христофер Коувел-Шах в статье «Nine language Performance roundup»)[4] Вопросы реализацииВопросы реализации могут также повлиять на фактическую эффективность. Это касается выбора языка программирования и способа, каким алгоритм фактически закодирован, выбора транслятора для выбранного языка или используемых опций компилятора, и даже используемой операционной системы. В некоторых случаях язык, реализованный в виде интерпретатора, может оказаться существенно медленнее, чем язык, реализованный в виде компилятора[5]. Есть и другие факторы, которые могут повлиять на время или используемую память, но которые оказываются вне контроля программиста. Сюда попадают выравнивание данных, детализация[англ.], сборка мусора, параллелизм на уровне команд и вызов подпрограмм[6]. Некоторые процессоры имеют способность выполнять векторные операции, что позволяет одной операцией обработать несколько операндов. Может оказаться просто или непросто использовать такие возможности на уровне программирования или компиляции. Алгоритмы, разработанные для последовательных вычислений, могут потребовать полной переработки для использования параллельных вычислений. Другая проблема может возникнуть с совместимостью процессоров, в которых команды могут быть реализованы по другому, так что команды на одних моделях могут быть относительно более медленными на других моделях. Это может оказаться проблемой для оптимизирующего компилятора. Измерение использования ресурсовИзмерения обычно выражаются как функция от размера входа n. Два наиболее важных измерения:
Для компьютеров, питающихся от батарей (например, лэптопов) или для очень длинных/больших вычислений (например, на суперкомпьютерах), представляют интерес измерения другого рода:
В некоторых случаях нужны другие, менее распространённые измерения:
ВремяТеорияДля анализа алгоритма обычно используется анализ временно́й сложности алгоритма, чтобы оценить время работы как функцию от размера входных данных. Результат обычно выражается в терминах «O» большое. Это полезно для сравнения алгоритмов, особенно в случае обработки большого количества данных. Более детальные оценки нужны для сравнения алгоритмов, когда объём данных мал (хотя такая ситуация вряд ли вызовет проблемы). Алгоритмы, которые включают параллельные вычисления, могут оказаться для анализа более трудными. ПрактикаИспользуются сравнительные тесты времени работы алгоритма. Многие языки программирования содержат функции, отражающие время использования процессора. Для долго работающих алгоритмов затраченное время также может представлять интерес. Результаты в общем случае нужно усреднять по серии тестов. Этот вид тестов может быть очень чувствителен к конфигурации «железа» и возможности работы других программ в то же самое время в многопроцессорной и многозадачной среде. Этот вид тестов существенно зависит также от выбора языка программирования, компилятора и его опций, так что сравниваемые алгоритмы должны быть реализованы в одинаковых условиях. ПамятьЭтот раздел касается использования основной памяти (зачастую, RAM) нужной алгоритму. Как и для временно́го анализа выше, для анализа алгоритма обычно используется анализ пространственной сложности алгоритма[англ.], чтобы оценить необходимую память времени исполнения как функцию от размера входа. Результат обычно выражается в терминах «O» большое. Существует четыре аспекта использования памяти:
Ранние электронные компьютеры и домашние компьютеры имели относительно малый объём рабочей памяти. Так, в 1949 EDSAC имел максимальную рабочую память 1024 17-битных слов, а в 1980 Sinclair ZX80 выпускался с 1024 байтами рабочей памяти. Современные компьютеры могут иметь относительно большое количество памяти (возможно, гигабайты), так что сжатие используемой алгоритмом памяти в некоторое заданное количество памяти требуется меньше, чем ранее. Однако существование трёх различных категорий памяти существенно:
Алгоритм, необходимая память которого укладывается в кэш компьютера, работает много быстрее, чем алгоритм, умещающийся в основную память, который, в свою очередь, будет много быстрее алгоритма, который использует виртуальное пространство. Усложняет ситуацию факт, что некоторые системы имеют до трёх уровней кэша. Различные системы имеют различное количество этих типов памяти, так что эффект памяти для алгоритма может существенно отличаться при переходе от одной системы к другой. В ранние дни электронных вычислений, если алгоритм и его данные не помещались в основную память, он не мог использоваться. В наши дни использование виртуальной памяти обеспечивает огромную память, но за счёт производительности. Если алгоритм и его данные умещаются в кэш, можно получить очень высокую скорость, так что минимизация требуемой памяти помогает минимизировать время. Алгоритм, который не помещается полностью в кэш, но обеспечивает локальность ссылок[англ.], может работать сравнительно быстро. Примеры эффективных алгоритмов
Критика текущего состояния программирования
Соревнования за лучший алгоритмСледующие соревнования приглашают принять участие в разработке лучших алгоритмов, критерий качества которых определяют судьи: См. также
Примечания
Литература
Ссылки
|
Portal di Ensiklopedia Dunia