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