Почему Go такой медленный (по сравнению с Java)? - PullRequest
108 голосов
/ 24 апреля 2010

Как мы могли видеть из Игра по тестированию языков программирования в 2010 году:

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

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

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

Ответы [ 10 ]

101 голосов
/ 24 апреля 2010

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

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

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

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

50 голосов
/ 24 апреля 2010

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

Performance

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

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

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

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

А вот еще несколько подробностей о компьютерной тестовой игре из недавней ветки списка рассылки.

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

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

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

33 голосов
/ 29 июля 2011

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

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

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

6 голосов
/ 09 января 2017

Все изменилось.

Я думаю, что правильный правильный ответ на ваш вопрос состоит в том, чтобы оспаривать идею, что идти медленно Во время вашего запроса ваше суждение было оправданным, но с тех пор компания Go получила много нового в плане производительности. Теперь он по-прежнему не так быстр, как С, но в общем смысле он далеко не в 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 голосов
/ 07 июня 2015

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

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

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

1 голос
/ 14 сентября 2018

Существует две основные причины того, что 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 выходит на первое место с комбинированным использованием памяти и временем работы.

1 голос
/ 14 ноября 2014

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

0 голосов
/ 17 мая 2019

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

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

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

0 голосов
/ 16 мая 2019

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

0 голосов
/ 08 августа 2012

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

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

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

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

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

...