Як швидко можна їхати?


39

Go - одна з небагатьох мов, яка повинна працювати «близько до металу», тобто вона компілюється, статично набирається та виконує код власним чином, без VM. Це має забезпечити перевагу швидкості у порівнянні з Java, C # тощо. Однак, схоже, це відстає від Java (див. Перестрілку з мови програмування )

Я припускаю, що менш зрілі компілятори несуть велику відповідальність за це, але чи є інші причини? Чи є щось, що притаманне дизайну Go, що заважало б йому працювати швидше, ніж, скажімо, Java? У мене дуже невмілий погляд на моделі виконання, але, здається, що принаймні в принципі він повинен бути здатний працювати швидше, ніж Java, завдяки виконанню нативного коду.


3
З огляду на досить розумний компілятор (та / або VM, та / або JIT-компілятор), дана мова завжди може йти швидше (ну, є фізичні обмеження, але це все). Цей істинний звичайно нікому не допомагає, поки цього досить розумного компілятора немає. Зауважте, що у Java вже є ці досить розумні реалізації, і вони неймовірно розумні. Ще один факт життя полягає в тому, що запуск коду має принаймні стільки ж впливу на продуктивність виконання, як і реалізація.

1
Я це розумію, але мені було цікаво, чи доцільно очікувати, що швидкість Go буде відповідати / наздоганяти, наприклад, Java, оскільки дозріває компілятор.
Грег Слодковіч

17
Мови програмування не мають швидкості. Ні мовні реалізації. Дана мовна реалізація має швидкість для деякого заданого вводу, і ця швидкість може дуже сильно залежати від введення.

8
Розбуди мене .. перед тим, як піти піти ... ЧАМ! . Вибачте, я не втримався. Ось приходять прапори .. сюди приходять прапори ..
Tim Post

2
@delnan - Або просто набагато простіше сказати "Java", ніж сказати "Java (TM) SE Runtime Environment (збірка 1.6.0_25-b06) Java HotSpot (TM) 64-бітний сервер VM (збірка 20.0-b11 , змішаний режим) ":-)
igouy

Відповіді:


46

Щодо мовного дизайну, насправді немає нічого такого, що повинно зробити Go повільніше, ніж Java взагалі. Насправді це дає більше контролю над компонуванням пам'яті ваших структур даних, тому для багатьох поширених завдань це повинно бути дещо швидше. Однак поточний первинний компілятор Go, планувальник, збирач сміття, бібліотека regexp та багато інших речей не особливо оптимізовані. Це невпинно поліпшується, але, здається, фокус робиться на тому, щоб бути корисним, простим та досить швидким у перемозі у мікробензинових оцінках.

У пов'язаному орієнтирі Go втрачає велику кількість Java на бінарному дереві та тесті regexp. Це тести системи управління пам'яттю та бібліотеки regexp відповідно. Управління пам'яттю Go може бути швидшим і, безумовно, покращиться з часом, а поточна стандартна бібліотека regexp - це заповнювач для набагато кращої реалізації, яка незабаром настає. Тож програш цим двом не дивно, і найближчим часом маржа повинна бути більш вузькою.

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

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

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

Я з нетерпінням чекаю, коли gccgo (компілятор Go, який використовує gcc codegen) зрілий; це повинно змусити Go майже збігатися з C для багатьох типів коду, що буде цікаво.


2
Молодці, для розуміння того, що завжди потрібно подивитися вихідний код і перевірити, що робиться!
igouy

1
Про час запуску Java для цих програм дивіться на сайті shootout.alioth.debian.org/help.php#java
igouy

2
Це саме той відповідь , який я сподівався, спасибі!
Грег Слодковіч

Набагато менше використання коду та пам'яті, компілюється в машинний код, краще розробляється. Все це перебирає недолік швидкості.
Moshe Revah

22
  1. Навіть не кажучи про те, які проблеми були вирішені, весь тест є безглуздим.
  2. JVM і CLR обидва використовують JIT для створення машинного коду. Немає причини, щоб це було повільніше. Це просто коштує вам віку завантажуватися.
  3. Go був розроблений для швидкого будівництва . У вас немає тонн часу компіляції та оптимізації часу завантаження. Go збирає власну стандартну бібліотеку до моменту завантаження програми Java.

Можливо, Go буде швидше під час виконання? Так. Чи буде коли-небудь швидше під час виконання? Не знаю. Можливо, розробники компіляторів додадуть додаткову оптимізацію за рахунок часу компіляції. Але я не думаю, що вони до цього мають великий інтерес. Вони працюють в Google.
Те, що вони хочуть, - це мова, яка дозволяє швидко розвиватися, і це добре робить те, що вони роблять. Пекло, навіть якби цей орієнтир був надійним, це означало б, що вони вдвічі швидші за С і в 14 разів швидші, ніж Python. Це більш ніж добре.
Обладнання дешеве, код дорогий. Код, як правило, стає більшим і повільнішим, коли ви вкладаєте гроші, апаратне забезпечення стає дешевшим і меншим. Вам потрібна мова, яка не потребує 4 рамки та 2000 класів, щоб досягти нічого корисного.
У дизайну Go немає нічого, що робить його повільним. Однак дизайнерам Go є щось властиве, що робить це повільніше, ніж збірка: здоровий глузд.


1
Більшість (усіх?) JIT компілюються під час виконання, а не при першому завантаженні коду. Цей машинний код може взагалі не генеруватися для якогось коду, а також може бути легко визнаний недійсним, наприклад, якщо objsу кожного разу for (obj : objs) { obj.meth() }є різні реалізації methта JIT намагається вкласти його. Звичайно, все це насправді користь у звичайних випадках, але все-таки заслуговує на увагу.

@delnan: V8 JIT вводить будь-який код перед його виконанням. Крім того, LLVM був побудований з урахуванням JITting, тому (доклавши певних зусиль), ви можете зробити будь-яку оптимізацію вчасно, що в іншому випадку станеться під час компіляції. Однак певні оптимізації, такі як аналіз втечі, реально працюють лише з JIT.
back2dos

3
>> Навіть не кажучи про те, які проблеми були вирішені << Подивіться, і ви побачите, що ці веб-сторінки НЕ говорять, які проблеми були вирішені. Насправді ви знайдете вихідний код програми, складіть команди, запускайте команди, версію мовної реалізації, ya da ya da ya
igouy

10

Я також помітив, що Go був особливо повільним у еталоні regex-dna . Расс Кокс пояснив, чому Go не був таким виконавцем у цьому конкретному орієнтирі . Причина полягає в тому, що пакет regexp Go використовує інший алгоритм узгодження, який погано спрацьовує в цьому конкретному еталоні, але може бути на величину швидший в інших орієнтирах. Крім того, Ruby, Python та інші мови сценаріїв використовують C реалізацію іншого алгоритму відповідності регулярних виразів .

Нарешті, Гра з комп'ютерними мовними орієнтирами складається з мікро-показників, які можуть не точно відображати багато характеристик вимірюваних мов і навіть опосередковувати неправильні враження. Цей дослідницький документ, нещодавно опублікований Google, дає більш точний огляд кількох мовних характеристик Go, Scala, Java та C ++ - зокрема, частини "V. Performance Performance". Отже, врешті-решт, Go майже майже такий, як голодна пам'ять, як Java (81% пам'яті Java) і споживає навіть 170% стільки пам’яті, скільки Scala (не вдалося знайти в статті, чи вважається споживання пам'яті JVM).

Але знову ж таки, Go молодий і все ще знаходиться у важкому розвитку (зміни API)! Багато поліпшень незабаром.


3
>> Цей дослідницький документ, нещодавно опублікований Google << Це не дослідницький документ, і він не був опублікований Google. Це звіт про досвід одного співробітника Google, представлений на семінарі Scala Days 2011.
igouy

>> може не точно відображати багато характеристик вимірюваних мов і навіть опосередковувати неправильні враження << Це так само стосується програм "розпізнавання циклу", і, ймовірно, стосується кожного порівняння продуктивності між різними мовами програмування. Насправді автор каже вам: "Ми не досліджуємо жодних аспектів багаторізкових або вищих механізмів типу ... ми також не проводимо важких чисельних обчислень ..."
igouy

@igouy На обкладинці ви можете прочитати "Google", і все відповідне покривається відповідними посиланнями. То чому це не "дослідницький документ, опублікований Google", якщо Google згадується зі своєю адресою штаб-квартири? Дослідницькі роботи не є лише науковим напрямом.
Алекс

На обкладинці ви можете прочитати поштову адресу, за якою можна зв’язатися з автором, та електронну адресу автора. Перевірте URL-адресу pdf, яку ви опублікували. Зверніть увагу на домен - days2011.scala-lang.org - Майстерня Scala Days 2011 "Майстерня Scala.
igouy

1

Іти швидше, ніж Python, і трохи повільніше, ніж Java. Мій брутальний досвід показав, що Go набагато швидше (на 1-2 порядки) швидше, ніж Python, і приблизно на 10-20% повільніше, ніж у Java. Однак Go є трохи швидше, ніж Java, якщо він використовувався з чотирьохядерним (x64). Go також набагато ефективніше з точки зору оперативної пам'яті пам'яті.

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

Зараз Java зазвичай працює швидше, ніж Go, тому що збір сміття Java набагато складніший. Хоча немає причини, що збирач сміття Go не міг бути набагато кращим. Генерація коду, ймовірно, набагато краще для Java на даний момент. Go має великий потенціал для покращення, наприклад, з підтримкою векторних інструкцій тощо.

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

У будь-якому випадку, це лише один досвід розробника.


4
Це 8-річне питання, і дешева обчислювальна потужність зробила це неактуально. Ваша відповідь також ґрунтується на "вашому почутті", а не на твердих даних. Я не хочу відштовхувати вас, але ...
Каяман
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.