Від чого залежить швидкість мови програмування?


38

Припустимо, що програма була написана двома різними мовами, нехай вони будуть мовою X та мовою Y, якщо їх компілятори генерують один і той же байт-код, чому я повинен використовувати мову X замість мови Y? Що визначає, що одна мова швидша за іншу?

Я запитую це, тому що часто ви бачите, як люди говорять такі речі, як "C - це найшвидша мова, ATS - мова швидка, як C". Я прагнув зрозуміти визначення поняття "швидкий" для мов програмування.


21
Якщо одна програма швидша за іншу, це означає, що вони не можуть мати однаковий байт-код.
svick

5
Мови - це лише поняття, яке використовується для написання програм, тому ви не можете реально говорити про швидкість мови.
Джухо

1
@Raphael Я вважаю, що це поза темою, незрозуміло і занадто широко. Хоча тема краще підходить до інженерії програмного забезпечення , я підозрюю, що вона буде закрита як "занадто широка".
Девід Річербі

2
Реалізація в сторону, «швидкість» неоднозначно, існують різні швидкості для реалізації, компіляції, виконання та налагодження, і ви взагалі збираєтеся торгувати з деяких для інших ( в іншому випадку ми б все використовувати на мові програмування)
Нік T

Як зазначено вище. Мови не генерують один і той же байт-код. Деякі мови простіше розібратися в байт-код. Деякі мають більш високий рівень абстракції.
суперлюмінація

Відповіді:


23

Існує багато причин, які можуть враховувати вибір мови X на мові Y. Читання програми, простота програмування, переносимість на багатьох платформах, наявність хороших середовищ програмування можуть бути такими причинами. Однак я розглядаю лише швидкість виконання, як вимагається у питанні. Здається, питання не враховує, наприклад, швидкість розвитку.

Дві мови можуть компілювати в один і той же байт-код, але це не означає, що буде створений той самий код,

Насправді байт-код - це лише код для конкретної віртуальної машини. Він має інженерні переваги, але не вносить принципових відмінностей при складанні безпосередньо для конкретного програмного забезпечення. Тож ви можете також розглянути можливість порівняння двох мов, складених для прямого виконання на одній машині.

Це говорило, що питання відносної швидкості мов є старим, починаючи з перших укладачів.

Протягом багатьох років, у ті часи, професіонали вважали, що рукописний код був швидшим, ніж компільований код. Іншими словами, машинна мова вважалася швидшою, ніж мови високого рівня, такі як Cobol або Fortran. І було, і швидше, і зазвичай менше. Мова високого рівня все ще розвивалася, тому що їх було набагато легше використовувати для багатьох людей, які не були комп'ютерними науковцями. Витрати на використання мов високого рівня навіть мали назву: коефіцієнт розширення, який міг би стосуватися розміру згенерованого коду (дуже важлива проблема в ті часи) або кількості дійсно виконаних інструкцій. Концепція була в основному експериментальною, але спочатку це співвідношення було більшим, ніж 1, оскільки компілятори виконували досить просту роботу на сьогоднішній день.

Таким чином машинна мова була швидшою, ніж скажімо, Fortran.

Звичайно, це змінювалося з роками, коли компілятори ставали все більш досконалими, до того, що програмування мовою складання зараз дуже рідкісне. Для більшості програм програми мовної збірки погано конкурують з кодом, створеним оптимізацією компіляторів.

Це свідчить про те, що одним з головних питань є якість компіляторів, доступних для розглянутої мови, їх здатність аналізувати вихідний код та оптимізувати його відповідно.

Ця здатність може певним чином залежати від особливостей мови підкреслювати структурно-математичні властивості джерела, щоб полегшити роботу компілятору. Наприклад, мова може дозволити включення висловлювань про алгебраїчні властивості визначених користувачем функцій, щоб дозволити компілятору використовувати ці властивості для цілей оптимізації.

Процес компіляції може бути простішим, отже, створення кращого коду, коли парадигма програмування мови наближається до особливостей машин, які інтегруватимуть код, будь то реальна чи віртуальна машина.

Інший момент - чи парадигми, реалізовані мовою, закриті для типу проблем, що запрограмовані. Очікується, що мова програмування, спеціалізована для конкретних парадигм програмування, буде дуже ефективно збирати функції, пов'язані з цією парадигмою. Отже, вибір мови програмування може залежати, від ясності та швидкості, від вибору мови програмування, адаптованої до типу заданої програми.

Популярність C для системного програмування, ймовірно, пов'язана з тим, що C близький до машинної архітектури, і що системне програмування також безпосередньо пов'язане з цією архітектурою.

Будь-яка інша проблема буде легше запрограмована, швидше виконання за допомогою логічного програмування та мов вирішення обмежень .

Складні реактивні системи можуть бути дуже ефективно запрограмовані спеціалізованими мовами синхронного програмування, як Esterel, яка втілює дуже спеціалізовані знання про такі системи та генерує дуже швидкий код.

Або, якщо взяти крайній приклад, деякі мови є високоспеціалізованими, наприклад, мовами опису синтаксису, які використовуються для програмування парсерів. Генератор синтаксичний аналізатор не що інше, як компілятор для таких мов. Звичайно, це не Тюрінг повно, але ці компілятори надзвичайно гарні за своєю спеціальністю: створення ефективних програм розбору. Область знань обмежена, методи оптимізації можуть бути дуже спеціалізованими та налаштованими дуже тонко. Ці генератори аналізаторів зазвичай набагато кращі, ніж те, що можна отримати, написавши код іншою мовою. Існує багато вузькоспеціалізованих мов з компіляторами, які створюють відмінний та швидкий код для обмеженого класу проблем.

Отже, при написанні великої системи може бути доцільним не покладатися на одну мову, а вибрати кращу мову для різних компонентів системи. Це, звичайно, викликає проблеми сумісності.

Іншим моментом, який часто має значення, є просто наявність ефективних бібліотек для запрограмованих тем.

Нарешті, швидкість не є єдиним критерієм і може суперечити іншим критеріям, таким як безпека коду (наприклад, щодо поганого введення чи стійкості до системних помилок), використання пам’яті, простота програмування (хоча сумісність парадигми насправді може допомогти цьому ), розмір коду об'єкта, технічне обслуговування програми тощо.

Швидкість не завжди є найважливішим параметром. Крім того, це може мати різні форми, як складність, яка може бути середньої складності або гіршої складності. Також у великій системі, як у меншій програмі, є частини, де швидкість є критичною, та інші, де це мало важливо. І це не завжди легко визначити заздалегідь.


Спасибі. Це щось подібне. Я шукав. Було важко знайти матеріал для предмета. Це досить з’ясовано.
Родріго Валенте

@ RodrigoAraújoValente Дякую, ви можете поглянути на це питання . Екстремістська думка полягає в тому, що компілятор для мови L може просто зв'язати інтерпретатор для L з вихідним кодом програми, нічого не роблячи. Тоді ви можете зробити краще, намагаючись оптимізувати обчислення пакету (часткове оцінювання). Чим більше ви оптимізуєте, тим швидше буде ваша мова. Питання тоді: що може допомогти вам оптимізувати? Відповіді можуть містити хороші знання спеціалізованої предметної області, допомогу програміста, складний аналіз тощо ...
babou

Під "тим самим байт-кодом" я здогадуюсь, що ви маєте на увазі "однаковий вид виконавчого представлення". Очевидно однакові виконувані файли працюватимуть з однаковою швидкістю (припускаючи ту ж саму систему виконання). (Я, мабуть, дивився б на це з точки зору інформації / комунікації. Теоретично програміст може знати все про програму та апаратне забезпечення, тоді як мова часто обмежує комунікацію (обмежує, які перетворення дозволені чи корисні), і компілятор може не знати мікроархітектурні деталі. Компіляція та розробник компілятора є аналогічними розвитку та навчанню ...
Пол А. Клейтон

Потім це потрапляє в те, що люди, як правило, хороші (наприклад, розпізнавання загальних зразків) порівняно з тим, що комп'ютери, як правило, хороші (наприклад, ведення записів і "арифметика"). Крім того, передача інформації під час виконання часто є більш зручною для комп’ютерів (профільна оптимізація може подолати деякий брак інформації, що передається через мову програмування). Динамічна оптимізація була б недоцільною для людських програмістів ...
Пол А. Клейтон

(хоча те саме можна сказати про написання всього програмного забезпечення на зборах кваліфікованими програмістами, орієнтованими на конкретне обладнання, до того часу, як програмне забезпечення було оптимізоване, змінилося б не лише обладнання, але і програмне забезпечення буде застарілим).
Пол А. Клейтон

16

Хоча з часом все працює на ЦП * , існують різні відмінності між різними мовами. Ось кілька прикладів.

Інтерпретовані мови Деякі мови інтерпретуються, а не складаються , наприклад, Python, Ruby та Matlab. Це означає, що код Python та Ruby не компілюється в машинний код, а швидше інтерпретується на ходу. Можна компілювати Python та Ruby у віртуальну машину (див. Наступний пункт). Дивіться також це питання . Інтерпретується, як правило, повільніше, ніж компільований код з різних причин. Інтерпретація не тільки може бути повільною, але й складніше робити оптимізацію. Однак якщо ваш код витрачає більшу частину часу на функції бібліотеки (у випадку з Matlab), продуктивність не погіршиться.

Віртуальна машина Деякі мови складаються в байт-код , придуманий "машинний код", який потім інтерпретується. Найважливішими прикладами є Java та C #. Хоча байтовий код може бути перетворений на машинний код на льоту, код, ймовірно, все ще працюватиме повільніше. У випадку з Java для перенесення використовується віртуальна машина. У випадку з C # можуть виникнути й інші проблеми, такі як безпека.

Накладні витрати Деякі мови торгують ефективністю для безпеки. Наприклад, деякі версії Pascal перевірять, чи не отримуєте ви доступ до масиву поза межами меж. Код C # "керується", і це має вартість. Ще один поширений приклад - збір сміття, який економить час для програміста, але не настільки ефективний, як руки з управління пам'яттю. Є й інші джерела накладних витрат, такі як інфраструктура для обробки винятків або для підтримки об'єктно-орієнтованого програмування.

* Насправді нині високопродуктивні системи також працюють з кодом на графічних процесорах і навіть на FPGA.


Отже, в основному, якщо мені потрібна більша продуктивність, то мені слід піти на компільовані мови? А про парадигми? Є причина вибрати функціональний замість oop, чи навпаки?
Родріго Валенте

Ваше зауваження щодо збору сміття трохи спрощене. Не завжди можна вирішити статично, коли виділена пам'ять більше не використовується. Навіть коли це вирішимо, це може бути дуже важко визначити без помилок. Отже, GC іноді необхідний і часто безпечніший (як перевірка меж масиву). Крім того, це може поєднуватися з явним випуском.
бабу

@ RodrigoAraújoValente Залежить. Crappy код часто компілюється в crappy код. Можливо, код, який ви можете написати на Python, насправді швидший, ніж код, який ви можете написати в C.
Рафаель

nit: як пояснили запитання, з яким ви пов’язані, python насправді не трактується "на ходу" :)
Eevee

Жодна з мов, які ви згадуєте в інтерпретованому розділі, не інтерпретується з ходу. Python компілюється в байт-код, Ruby був компільований в AST, але я вважаю, що тепер він збирається в байт-код. Matlab, я вважаю, що насправді складається JIT. Насправді я не знаю жодної мовної реалізації, яка інтерпретує речі на ходу, а не принаймні компілюючи у якесь уявлення віртуальної машини.
Вінстон Еверт

5

Існують різні фактори вибору X замість Y, наприклад

  • Простота навчання
  • Простота розуміння
  • Швидкість розвитку
  • Допомога в застосуванні правильного коду
  • Виконання складеного коду
  • Підтримувані середовища платформи
  • Переносність
  • Придатний за призначенням

Деякі мови підходять для розробки бізнес-проектів, таких як C # або Python, але з іншого боку, деякі з них корисні для системного програмування, як C ++.

Ви повинні визначити, на якій платформі ви збираєтеся працювати та яку програму ви збираєтесь створити.


1
Отже, як я визначаю продуктивність компільованого коду? Це в основному те, що змусило мене зайнятися цим питанням.
Родріго Валенте

6
Ця відповідь, безумовно, має гарну пораду, але я не бачу, як вона відповідає на питання, що стосується швидкості як фактора вибору для мови.
бабу

@ RodrigoAraújoValente Вони навіть не можуть бути складені кодом (якщо інтерпретується ваша мова).
Рафаель

1
Ви можете додати "Хороші бібліотеки" та "Хороші інструменти".
Рафаель

@ RodrigoAraújoValente Ви запускаєте його та профілюєте його.
Кайл

2

"Найшвидша" мова програмування, яку ви можете отримати на будь-якій платформі, - це мова монтажу для чіпсету, з яким ви маєте справу. На цьому рівні немає перекладів. Однак потрібно мати певні знання про те, як чіпсет виконує інструкції, особливо ті, які можуть робити паралельно.

Перетворення від C до складання дуже "неглибоке", що воно знаходиться поблизу один до одного, але воно читабельніше. Однак він має багато шарів над ним завдяки стандартним бібліотекам для покращення портативності. Існує не так багато речей, які потрібно було б зробити компілятору, щоб дійти до асемблерного коду, і більш сильні оптимізації, як правило, існують для внесення змін до конкретних машин.

C ++ додає більш багату мову. Однак оскільки мова додає стільки складних умов, компілятору стає складніше створити оптимальний код для платформи.

Потім переходимо на інший бік шкали. Інтерпретовані мови. Вони, як правило, найповільніші, тому що, крім того, щоб виконувати роботу, є час, який витрачається на розбір коду та перетворення його на машинні дзвінки.

Тоді у нас є ті, що знаходяться між ними. Як правило, вони мають рівень віртуальної машини, оптимізований для платформи. І компілятор створить код для виконання віртуальної машини. Іноді це відбувається все відразу, як perl або pascal або ruby ​​або Python. Або в кілька етапів, як java.

Деякі з цих віртуальних машин додають поняття компілятора JIT, що також прискорює час виконання, створюючи код машинного рівня, а не перекладаючи проміжний байт-код.

Деякі віртуальні машини мають низький рівень, що дозволяє менше перекладати з байтового коду в машинний код. Що прискорює роботу, зберігаючи мобільність.


Історично C розроблений для легкого перекладу в машинний код. Однак у більшій мірі перетворення C на ефективний код С вимагає, щоб компілятор з'ясував, що намагався зробити програміст, а потім переклав цей намір у машинний код. Наприклад, історично машинний кодекс, еквівалентний *p++=*q++;на багатьох машинах, був швидшим, ніж array1[i]=array2[i];на багатьох процесорах, зворотній зв'язок часто відповідає дійсності, і тому компілятори можуть перетворити колишній стиль коду на другий - навряд чи "дрібне" перетворення.
supercat

Зазвичай, якщо ви -O0це зробите, оптимізація не зробить. Оптимізація - це бонус, який ви отримуєте за допомогою компілятора, але мова сама по собі може перевести близько одного до одного для складання.
Архімед Траяно

2

Точка, про яку ще не було сказано, полягає в тому, що в деяких мовах виконання одного і того ж фрагмента коду багато разів завжди буде виконувати ту саму послідовність дій; комп’ютер, таким чином, повинен лише один раз визначити, що повинен робити розділ коду. Однією з головних переваг діаграми JavaScript "суворо використовувати" є те, що після того, як механізм JavaScript з'ясує, що робить фрагмент коду, він може використовувати цю інформацію при наступному запуску; без "строгого використання" не може.

Наприклад, за відсутності "використовувати суворо", фрагмент коду типу:

function f() { return x; }

може повернути змінну X у контексті безпосереднього виклику, якщо вона є, або змінну X із зовнішнього контексту виклику, або вона може повернутися Undefined. Гірше, в циклі, як:

for (i=0; i<40; i+=1) { g(i); }

немає можливості, щоб двигун JavaScript знав, що g()може зробити з i[або для gсебе з цього приводу. Оскільки gабо iміг цілком законно перетворитись iна рядок, двигун JavaScript не може просто використовувати числове додавання та числове порівняння в циклі, але повинен кожного разу проходити цикл, щоб перевірити, чи зробив який-небудь із функцій викликів щось iчи g. На відміну від цього, в діалекті "використовувати строгий" [дещо розумний] движок JavaScipt може вивчити наведений вище код і знати, що кожен прохід через цикл буде використовувати ту саму числову змінну і викликати ту саму функцію. Таким чином, потрібно буде лише визначити iта функціонуватиg один раз, а не шукати їх під час кожного проходу через цикл - значна економія часу.


2

Ну, тут є кілька досить професійних відповідей, цей не є їм близьким, але може бути для вас інтуїтивно зрозумілим.

Можливо, ви багато разів чули, що коли вам потрібно виконати завдання якнайшвидше, ви хочете написати код, який виконує його в зборі. Це тому, що ви виконуєте лише ті команди, які вам фактично потрібні для виконання завдання, і більше нічого. Хоча на мові високого рівня ви могли реалізувати це завдання в декількох рядках, компілятору все ж потрібно перевести їх на машинну мову. Цей переклад не завжди є мінімалістичним, тому що ви можете писати його безпосередньо. Це означає, що машина витратить багато годин на виконання команд, які ви могли б запасти.

Хоча компілятори сьогодні дуже складні, вони все ще не ефективні, оскільки це можуть бути найкращі програмісти для складання.

Продовжуючи в цьому напрямку, ці непотрібні команди зростають у кількості (як правило) у міру вирівнювання мови. (це не на 100% справедливо для всіх мов високого рівня)

Тож для мене мова X швидша, ніж мова Y (під час виконання), якщо для певного фрагмента коду машинний код X коротший, ніж у Y.


Збірка повністю рок. Хоча справжній художник перевершує найкращих компіляторів.
Йохан - відновити Моніку

1

На це питання важко відповісти остаточно, оскільки він настільки складний і багатовимірний (це майже як, наприклад, порівняння марок автомобілів за різними критеріями), але є нові наукові дослідження, в тому числі відмінне сховище коду, відоме як код Rosetta , ( огляд wikipedia ). Це опитування 2014 року, проведене Nanz та Furia, вивчає це питання досить остаточно та науково, ґрунтуючись на наступних типових критеріях та рідкісному кількісному аналізі типово суб'єктивних якостей коду. Реферат містить деякі об'єктивно обґрунтовані висновки та узагальнення. (Сподіваємось, інші дослідження, засновані на цих результатах, можуть бути зроблені в майбутньому.)

  • RQ1. Які мови програмування створюють більш стислий код?

  • RQ2. Які мови програмування компілюються у менші виконувані файли?

  • RQ3. Які мови програмування мають кращу продуктивність роботи?

  • RQ4. Які мови програмування ефективніше використовують пам'ять?

  • RQ5. Які мови програмування менш схильні до відмов?

Анотація. Іноді дебати з мов програмування є більш релігійними, ніж науковими. Питання про те, яка мова є більш лаконічною чи ефективною, чи робить розробників більш продуктивними, обговорюються із запалом, і їх відповіді занадто часто базуються на анекдотах та необґрунтованих переконаннях. У цьому дослідженні ми використовуємо в основному невикористаний дослідницький потенціал коду Rosetta, кодового сховища рішень загальних завдань програмування на різних мовах, який пропонує великий набір даних для аналізу. Наше дослідження базується на 7 087 програмах рішення, що відповідають 745 завданням у 8 широко використовуваних мовах, що представляють основні парадигми програмування (процедурні: C і Go; об'єктно-орієнтовані: C # і Java; функціональні: F # і Haskell; сценарії: Python і Ruby). Наш статистичний аналіз виявляє, особливо, що: функціональні мови та мови сценаріїв більш стислі, ніж процедурні та об'єктно-орієнтовані мови; C важко перемогти, коли мова йде про швидку швидкість на великих входах, але відмінності в роботі над введеннями середнього розміру менш виражені і дозволяють навіть інтерпретованим мовам бути конкурентоспроможними; складені сильно типізовані мови, де в процесі компіляції може бути виявлено більше дефектів, менш схильні до відмов виконання, ніж інтерпретовані або слабо типізовані мови. Ми обговорюємо наслідки цих результатів для розробників, мовних дизайнерів та освітян. де більше дефектів може бути виявлено під час компіляції, вони менш схильні до відмов виконання, ніж інтерпретовані або слабо типізовані мови. Ми обговорюємо наслідки цих результатів для розробників, мовних дизайнерів та освітян. де більше дефектів може бути виявлено під час компіляції, вони менш схильні до відмов виконання, ніж інтерпретовані або слабо типізовані мови. Ми обговорюємо наслідки цих результатів для розробників, мовних дизайнерів та освітян.


0

Комп'ютерні мови - це лише абстракція команд, щоб пояснити комп’ютеру, що робити.

Можна навіть писати на комп'ютерній мові Pythonта компілювати її за допомогою компілятора С (цитона).

Маючи це на увазі, швидкість комп'ютерних мов не можна порівняти.

Але ви можете порівняти компілятори для однієї мови на деякій відстані. Наприклад GNU Cкомпілятор проти Intel Cкомпілятора. (Пошук еталону компілятора)


2
Якщо ви хочете коментувати питання, скористайтеся полем для коментарів, а не своєю відповіддю. Зауважте, що це обмін стека інформатики, і інформатика не програмує, так само як література не є текстовою обробкою. Питання програмування живуть на програмі інженерії програмного забезпечення або переповнення стека .
Девід Річербі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.