Почему Go настолько медленный (по сравнению с Java)?

Как мы могли видеть из игры The Computer Benchmarks Game в 2010 году:

  • Го в среднем в 10 раз медленнее, чем С
  • Go в 3 раза медленнее, чем Java !

Как это может быть, учитывая, что компилятор Go создает собственный код для выполнения?
Незрелые компиляторы для Go? Или есть какая-то внутренняя проблема с языком Go?

РЕДАКТИРОВАТЬ:
Большинство ответов отрицают внутреннюю медлительность языка Go, утверждая, что проблема заключается в незрелых компиляторах.
Поэтому я сделал несколько собственных тестов для вычисления чисел Фибоначчи: итерационный алгоритм запускается в Go (freebsd, 6g) с той same скоростью, что и в C (с опцией O3). Скучный рекурсивный работает в Go в 2 times медленнее, чем в C (с опцией -O3; с -O0 - то же самое). Но я не видел 10-кратного падения, как в игре Benchmarks.

Ответ 1

Компиляторы 6g и 8g не особенно оптимизированы, поэтому код, который они создают, не особенно быстрый.

Они предназначены для быстрой работы и создания кода, который ОК (есть немного оптимизации). gccgo использует GCC существующие проходы оптимизации и может обеспечить более точечное сравнение с C, но gccgo еще не завершена.

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

FWIW, мой собственный очень тривиальный тест с Go, когда я смотрел на него (цикл целочисленного добавления, в основном), gccgo создавал код в направлении быстрого конца диапазона между gcc -O0 и gcc -O2 для эквивалентных C. Go не является по своей сути медленным, но компиляторы все еще не делают. Вряд ли удивительно для языка, который 10 минут.

Ответ 2

В следующем выпуске Go FAQ должно появиться что-то похожее на следующее.

Спектакль

Почему Go плохо работает на бенчмарке X?

Одна из целей разработки Go состоит в том, чтобы приблизиться к производительности C для сопоставимых программ, но в некоторых тестах он работает довольно плохо, в том числе в тестах/тестах. Самые медленные зависят от библиотек, для которых версии с сопоставимой производительностью недоступны в Go. Например, pidigits зависит от математического пакета с высокой точностью, а версии C, в отличие от Go, используют GMP (который написан на оптимизированном ассемблере). Тесты, которые зависят от регулярных выражений (например, regex-dna), по сути, сравнивают пакет regexp Go stopgap со зрелыми, высоко оптимизированными библиотеками регулярных выражений, такими как PCRE.

Тестовые игры выигрывают благодаря обширной настройке, и версии Go для большинства тестов требуют внимания. Если вы измерите сравнимые программы на C и Go (один из примеров - обратное дополнение), вы увидите, что эти два языка гораздо ближе к исходной производительности, чем этот набор.

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

А вот еще некоторые подробности об игре Computer Benchmarks Game из недавней ветки списка рассылки.

Сборка мусора и производительность в gccgo (1)

Сборка мусора и производительность в gccgo (2)

Важно отметить, что Computer Benchmarks Game - это всего лишь игра. Люди с опытом в измерении производительности и планировании мощности тщательно сопоставляются с реалистичными и реальными рабочими нагрузками; они не играют в игры.

Ответ 3

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

Недавно я написал сервер сообщений на Python, используя Tornado + TornadIO + ZMQ, и для моего первого проекта Go я решил переписать сервер в Go. До сих пор, получив сервер к той же функциональности, что и версия Python, мои тесты показывают мне увеличение скорости на 4.7x в программе Go. Имейте в виду, я только кодировал в Go, может быть, неделю, и я уже более 5 лет кодируюсь на Python.

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

Ответ 4

Времена изменились.

Я думаю, что текущий правильный ответ на ваш вопрос состоит в том, чтобы оспаривать идею, которая идет медленно. Во время вашего запроса ваше суждение было оправданным, но с тех пор компания Go получила много нового в плане производительности. Теперь, он все еще не так быстр, как C, но далеко не в 10 раз медленнее, в общем смысле.

Тесты компьютерного языка

На момент написания статьи:

source  secs    KB      gz      cpu     cpu load

reverse-complement
1.167x
Go      0.49    88,320  1278    0.84    30% 28% 98% 34%
C gcc   0.42    145,900 812     0.57    0% 26% 20% 100%

pidigits
1.21x
Go      2.10    8,084   603 2.10    0% 100% 1% 1%
C gcc   1.73    1,992   448 1.73    1% 100% 1% 0%

fasta
1.45x
Go      1.97    3,456   1344    5.76    76% 71% 74% 73%
C gcc   1.36    2,800   1993    5.26    96% 97% 100% 97%

regex-dna
1.64x
Go      3.89    369,380 1229    8.29    43% 53% 61% 82%
C gcc   2.43    339,000 2579    5.68    46% 70% 51% 72%

fannkuch-redux
1.72x
Go      15.59   952 900 62.08   100% 100% 100% 100%
C gcc   9.07    1,576   910 35.43   100% 99% 98% 94%

spectral-norm
2x
Go      3.96    2,412   548 15.73   99% 99% 100% 99%
C gcc   1.98    1,776   1139    7.87    99% 99% 100% 99%

n-body
2.27x
Go      21.73   952 1310    21.73   0% 100% 1% 2%
C gcc   9.56    1,000   1490    9.56    1% 100% 1% 1%

k-nucleotide
2.40x
Go      15.48   149,276 1582    54.68   88% 97% 90% 79%
C gcc   6.46    130,076 1500    17.06   51% 37% 89% 88%

mandelbrot
3.19x
Go      5.68    30,756  894 22.56   100% 100% 99% 99%
C gcc   1.78    29,792  911 7.03    100% 99% 99% 98%

Тем не менее, он сильно страдает от бинарного бенчмарка:

binary-trees
12.16x
Go      39.88   361,208 688 152.12  96% 95% 96% 96%
C gcc   3.28    156,780 906 10.12   91% 77% 59% 83%

Ответ 5

Несмотря на не очень хорошую эффективность Go в отношении использования циклов ЦП, модель параллелизма Go намного быстрее, чем, например, модель потоков в Java, и может быть сравнима с моделью потоков C++.

Обратите внимание, что в тесте с кольцами потоков Go был в 16 раз быстрее, чем Java. В том же сценарии Go CSP был почти сопоставим с C++, но использовал в 4 раза меньше памяти.

Огромная сила языка Go заключается в его модели параллелизма, CSP, заданной Тони Хоаром в 70-х годах, которая проста в реализации и подходит для одновременных нужд.

Ответ 6

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

Тест бинарных деревьев описывается как " адаптация эталона для тестирования GC". Go GC в настоящее время не находится там, где Java или С#, а также на рабочих нагрузках с множеством объектов, содержащих указатель, и большим количеством давления в памяти. Если это было проблемой в приложении Live Go, вы бы использовали свой собственный пул объектов/бесплатный список для повторного использования объектов этого типа [edit: люди в CloudFlare, которые используют Go, только что опубликовано о том, как это сделать]. Это подход к управлению расходами GC, используемых на языках GC'd в целом, но поскольку связанная страница отмечает, что он исключен правилами для этого теста.

В тесте pidigits используется библиотека Go-number-math, которая медленнее, чем такие, как C GMP или, возможно, библиотеки Java. Если производительность вашего приложения ограничена скоростью бигнама (может быть фактором криптографии с открытым ключом и некоторыми приложениями math/sci, менее одного, например, для веб-приложений), вы хотите вызвать в библиотеку C из Перейдите или просто используйте другой язык.

Многие другие отличия, вероятно, сводятся к менее оптимизированному генерации кода, как говорится в принятом ответе.

Вы хотите сделать свой выбор с более широкой перспективой, чем просто тесты, конечно. Многие пользователи Go, включая меня, похоже, работают на языках сценариев и, похоже, любят вывод типа, concurrency tools, и быстрая компиляция. С другой стороны, относительная незрелость экосистемы (по сравнению с Java, C-языками или даже Python) является большим недостатком, вероятно, больше, чем эталонные числа. Кажется, стоит зайти, если у вас есть интерес, в любом случае.

Ответ 7

Все сводится к тому, сколько времени требуется, чтобы что-то закодировать и как мало работы необходимо для получения наилучшей производительности из того, что она разрабатывается. Все остальное - просто страстное стремление, которое не имеет большого значения в бизнесе....... что-то типа.

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

Я написал некоторые программы Голанга.... быстро, как дерьмо через гуся...... и если бы моя задача заключалась в том, чтобы судить серьезную математику целый день... Я не думаю, что буду использовать Java или Go для этого... Я бы использовал язык, предназначенный для такого рода вещей.

Ответ 8

Я думаю, что часто забываемый факт состоит в том, что компиляция JIT может быть > статической компиляцией специально для (runtime) поздних связанных функций или методов. Точка доступа JIT решает на RUNTIME, какие методы встроены, он даже может настроить компоновку данных на размер/архитектуру кэша процессора, в котором он в настоящее время работает. C/С++ вообще может составлять (и в целом все равно будет работать лучше), имея прямой доступ к оборудованию. Для Go вещи могут выглядеть по-другому, так как их более высокий уровень по сравнению с C, но в настоящее время не хватает системы оптимизации/времени компиляции. Моя кишка говорит мне, что Go может быть быстрее, чем Java, поскольку Go не применяет указатель, который так много гоняется и поощряет лучшую локальность структуры данных + требует меньшего выделения.

Ответ 9

Существует две основные причины того, что Java быстрее, чем Go и C++, и во многих случаях может быть быстрее, чем C:

1) JIT-компилятор. Он может встроить вызовы виртуальных функций на нескольких уровнях, даже с классами OO, в зависимости от профиля времени выполнения. Это невозможно на статически скомпилированном языке (хотя может помочь новая перекомпиляция, основанная на записанном профиле). Это очень важно для большинства тестов, в которых используются повторяющиеся алгоритмы.

2) ГК. Распределение памяти на основе GC практически свободно по сравнению с malloc. А штраф "бесплатно" может амортизироваться в течение всего времени выполнения - часто пропускается, потому что программа завершается до того, как весь мусор нужно будет собрать.

Есть сотни (тысячи?) Чрезвычайно талантливых разработчиков, делающих GC/JVM эффективной. Думать, что ты можешь "кодировать лучше всех" - глупость. В глубине души это проблема человеческого эго - людям трудно смириться с тем, что при надлежащем обучении талантливых людей компьютер будет работать лучше, чем люди, которые его запрограммировали.

Кстати, C++ может быть так же быстр, как C, если вы не используете и функции OO, но тогда вы довольно близки к программированию на C для начала.

Самое главное, что "различия в скорости" в этих тестах обычно не имеют смысла. Затраты на ввод-вывод на несколько порядков превышают различия в производительности, и поэтому правильные конструкции, которые минимизируют затраты на ввод-вывод, всегда выигрывают - даже на интерпретируемом языке. Очень немногие системы связаны с процессором.

В заключение отметим, что "игра в компьютерные языковые тесты" называется "научной мерой". Тесты полностью ошибочны, например, если вы просматриваете тесты Java для nbody. Когда я запускаю тесты на одной и той же ОС/оборудовании, я получаю примерно 7,6 секунды для Java и 4,7 секунды для C - что вполне разумно - не в 4 раза медленнее, чем в отчетах о тестах. Это клик-приманка, поддельные новости, предназначенные для генерации трафика сайта.

В качестве заключительного, заключительного замечания... Я выполнил тесты, используя Go, и это было 7,9 секунды. Тот факт, что когда вы нажимаете Go, он сравнивает его с Java, а когда вы нажимаете Java, он сравнивает его с C, должен быть красным флагом для любого серьезного инженера.

Для реального сравнения Java, Go и C++ см. Https://www.biorxiv.org/content/10.1101/558056v1 предупреждение о спойлере, Java выходит на первое место по сырой производительности, а Go выходит на первое место с комбинированным использование памяти и настенное время.

Ответ 10

c++ существовал, потому что он был элегантен, давал вам больше абстракции, помимо c, с нулевой производительностью и затратами на память. ZERO Go существует потому, что по многим причинам это слишком приятно, чтобы поделиться здесь. но если производительность во время исполнения находится на уровне другой импровизации (python), то спасибо, но не спасибо!

Теперь доказательство того, что все это пропаганда: мой канадский брат сказал: я и Томсон ждали сборки c в течение 45 минут, миллионы за миллионами исходного кода. Все идет нормально. но эти строки уже написаны, и плохой код - плохой код (потому что он также жаловался на то, как трудно отлаживать повреждение стека, как вы это называете). Теперь мой вопрос QED прост. кто собирается написать эти миллионы строк кода go, чтобы с удовольствием насладиться быстрым временем сборки?!? если производительность посредственная, хорошо, я скажу вам, кто. НИКТО! возможно, некоторые мальчики зарабатывают на системах, где производительность во время выполнения не имеет значения. но я хотел бы поделиться с вами простым секретом: быстро это хорошо, медленно это плохо.

я также назвал python импровизацией и не говоря уже о галактическом отсутствии какой-либо профессиональной подсказки из 2.x против 3.x, когда вы импортируете это, ZEN ZERO должен сказать: COMPILER - ВАШ ДРУГ!

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

компании, получающие доход от не программных источников, ну, они могут позволить себе любимые проекты, такие как "go", но я гарантирую вам, что если бы они зависели от производительности во время выполнения (например, как Amazon), они не могли бы себе это позволить, даже на секунду (в то время как миллионы транзакций происходят).

почему кубернетесь банкой с червями?!? если го так чисто... почему система рутин (хорошая в теории) такая медленная и глючная?!? если это так хорошо, зачем ему неочевидные помощники от более традиционных потоковых вещей (семафоры, мьютексы, вы называете это). Лично я считаю, что это божественно, но научно-фантастически, так же, как оптимизирующий компилятор go, который ничего не оптимизирует (в основном потому, что невозможно оптимизировать математически неопределенные концепции, возникшие в результате того, что конечные пользователи/программисты проектируют языки в компаниях, не занимающихся разработкой программного обеспечения). домашнее программирование для гугл)

То же самое в Java. язык/компромисс синего воротничка многие люди используют, потому что они не знают лучше.

у java и С# есть шаблоны?!? спросите Андерс, немаркетинговый ответ НЕ ОНИ НЕ. Только c++ и Delphi делают. то, что у них есть, это слепки с сахарным покрытием не больше, не меньше этого.

Кто-нибудь из вас знает разницу в качестве (во время выполнения, с точки зрения производительности во время выполнения) между машинным кодом стека (java, С#) и кодом регистров?!? это 2x

зачем нужен сборщик мусора?!? потому что у них слишком много мусора. может ли утечка памяти в Java и С# (и, конечно, идти) → Конечно.

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

и нехватка упс?!? ты, должно быть, шутишь. это как мальчики из Microsoft, в 90-х, учили всех, как писать настоящие программы (например, COM, DCOM), потому что наследование реализации вредно для вас... ДА

я не верю, что у Google есть (или мог позволить себе) настоящий автор на языке stroustroup, они, вероятно, могли бы позволить себе anders (что, кстати, не для продажи, по крайней мере, вы, ребята, делали штуковину вместе)) и это не нехватка денег, о которых мы говорим, это отсутствие здравого смысла и реальных потребностей, которые потребуются Google (и многим другим, Apple будет идеальным/даже лучшим примером), чтобы это произошло. плюс, языки реальной жизни рождаются в смирении, думают о с, думают об объектном паскале (не говоря уже о) и c++. в смирении и невыразимом гении. те же слова о невозможности нанять реального оптимизатора жизни (это еще более невозможно, так как вещи, рожденные сломанными, не могут быть оптимизированы). не верьте мне, возьмите триллион обезьян, генетически сконструируйте их, хорошо кормите их, держите их счастливыми и дайте им бумагу и ручки на миллион лет. сколько сонетов Шекспира они напишут? НУЛЬ

так здесь и сейчас

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

всем доброй ночи, сейчас 2:40, я все еще жду, пока мои глупые ядра соберутся (как они говорят... :-) LOL

будь хорошим

Ответ 11

в linux время выполнения go очень быстрое и вполне сопоставимо с c/c++. среда выполнения go под windows и unix не в одной лиге

сравнение с java не так важно, go предназначен как для разработки системы, так и для разработки приложений (поскольку java больше похож на blue collar только для разработки приложений). не буду вдаваться в подробности, но когда такие вещи, как kubernetes написаны на ходу, вы понимаете, что это не дружелюбная игрушка для корпоративных консультантов

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

Ответ 12

На самом деле, Go не только элегантен и эффективен во время разработки, но и суперэффективен во время выполнения. Ключ должен использовать правильную операционную систему, то есть LINUX. Результат профилирования производительности в Windows и Mac OS, из-за отсутствия лучшего слова, на один-два порядка ниже.

Ответ 13

Вы все здесь говорите о теории. цели дизайна, рутины хорошо продуманы и т.д. (в основном, слоники, разговоры дешевы, поверьте мне!) идти - это, к сожалению, дорога в ад, вымощенная благими намерениями. мы говорим о производительности во время выполнения, а не о производительности во время компиляции или во время компоновки. Чтобы добиться производительности во время компиляции, оптимизирующий компилятор вообще не оптимизирует, давайте забудем об отсутствии oop (в этой главе это забавно, lol здесь) и препроцессора. но достаточно сказано. давай возьмём простое задание. сгенерируйте порядка 200 000 простых чисел по порядку. ОК?

давайте посмотрим код c, c++ и go, если хотите, я могу добавить код java и С#. Вы строите их сами, управляете ими и идете оттуда. это конкретные, а не сказки из журналов по программированию и/или маркетинга в Google.

вот код (c, c++, С#, java, pascal, go, вы бы тоже хотели сборку? я думаю, это было бы унизительно, верно?)

https://drive.google.com/file/d/1SFkAY5TLUIPULm78SxJrQd3qfpHQDGsf/view?usp=sharing

https://drive.google.com/file/d/1RHQQXcyFul_ekSy6iXhVsdh_CeRlCk-g/view?usp=sharing

https://drive.google.com/file/d/1d6ZHLut9ANmuA79S1vkC_djtp841ORP9/view?usp=sharing

https://drive.google.com/file/d/1b9lNfZWJOP6PnNuaXCTu1-szVZC4957h/view?usp=sharing

https://drive.google.com/file/d/1IEaAtivk0mV6zQW15fIQeJssxBjrtFzd/view?usp=sharing

и наконец поехали

https://drive.google.com/file/d/1f9J33LeptagXGlRuzMzH-FeJOwZcMrpE/view?usp=sharing

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

go примерно на порядок (ДЕСЯТЬ РАЗ) медленнее, чем c/c++, и примерно в 5 раз по сравнению с java & С#. используйте -O3, конечно, не стесняйтесь использовать ЛЮБОЙ компилятор go, который вам нравится, для паскаля вы можете использовать -O4, то же самое...

это не достаточно хорошо для остальных из нас, для ребят из Google (таких как авторы go), создающих миллиард бессмысленных строк плохо разработанных c-приложений, ну, возможно, go - это полезно.

Теперь о плохом качестве (может быть червей), возникающем из-за использования стандартных процедур, здесь есть ссылка, из собственных обучающих фильмов Google, из YouTube, их собственной платформы, верно?

10000 миль в небе, маркетинг Mumbo Jumbo:

https://www.youtube.com/watch?v=f6kdp27TYZs&t=187s

а теперь пример из реальной жизни, РЕАЛЬНОСТЬ:

https://www.youtube.com/watch?v=QDDwwePbDtw&t=1680s

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

выплеснуть

Ответ 14

И Java, и C более ясны с их определениями данных и методов (функций). C статически типизирован, а Java - меньше, с его моделью наследования. Это означает, что способ обработки данных во многом определяется во время компиляции.

Go более неявно с его определениями данных и функций. Встроенные функции более общие по своей природе, и отсутствие иерархии типов (например, Java или С++) дает недостаток скорости.

Имейте в виду, что цель Google для языка Go - иметь приемлемый компромисс между скоростью выполнения и скоростью кодирования. Я думаю, что они поражают хорошее сладкое пятно на их ранней попытке, и все будет только улучшаться по мере того, как будет сделано больше работы.

Если вы сравниваете Go с более динамически типизированными языками, основным преимуществом которых является скорость кодирования, вы увидите преимущество скорости выполнения Go. Go в 8 раз быстрее, чем perl, и в 6 раз быстрее, чем Ruby 1.9 и Python 3 на тех тестах, которые вы использовали.

В любом случае, лучший вопрос, который следует задать, - это хороший компромисс в простоте программирования и скорости исполнения? Мой ответ был "да", и он должен стать лучше.