Как быстро можно идти?

39

Go - один из немногих языков, которые должны работать «близко к металлу», то есть он скомпилирован, статически типизирован и выполняет код без изменений, без виртуальной машины. Это должно дать ему преимущество в скорости перед Java, C # и тому подобным. Кажется, однако, что это позади Java (см. Shootout языка программирования )

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

Грег Слодкович
источник
3
При достаточно умном компиляторе (и / или ВМ, и / или JIT-компиляторе) данный язык всегда может работать быстрее (ну, есть физические ограничения, но это так). Этот трюизм, конечно, никому не поможет, пока этого достаточно умного компилятора нет. Обратите внимание, что в Java уже есть достаточно умные реализации, и они невероятно умны. Еще один факт из жизни заключается в том, что выполнение кода оказывает как минимум такое же влияние на производительность во время выполнения, как и реализация.
1
Я понимаю это, но мне было интересно, разумно ли ожидать, что скорость Go будет соответствовать / превосходить, например, Java по мере развития компилятора.
Грег Слодкович,
17
Языки программирования не имеют скорости. Не делают языковые реализации. Реализация данного языка имеет скорость для некоторого заданного ввода, и эта скорость может очень сильно зависеть от ввода.
8
Разбуди меня .. прежде чем идти идти ... WHAM! , Извините, я не удержался. Сюда приходят флаги .. здесь приходят флаги ..
Tim Post
2
@delnan - Или просто сказать «Java» гораздо проще, чем сказать «Java (TM) SE Runtime Environment (сборка 1.6.0_25-b06) Java HotSpot (TM) 64-битная виртуальная машина сервера (сборка 20.0-b11) , смешанный режим) ":-)
igouy

Ответы:

46

С точки зрения языкового дизайна, нет ничего, что могло бы сделать Go медленнее, чем Java в целом. Фактически, это дает вам больший контроль над структурой памяти ваших структур данных, поэтому для многих общих задач это должно быть несколько быстрее. Однако текущий основной компилятор Go, планировщик, сборщик мусора, библиотека регулярных выражений и многие другие вещи не особенно оптимизированы. Это неуклонно улучшается, но, кажется, основное внимание уделяется тому, чтобы быть полезным, простым и достаточно быстрым по сравнению с победой в микробенчмарках.

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

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

Java побеждает в тесте mandelbrot, потому что это все арифметика и циклы с плавающей запятой, и это прекрасное место для JVM, чтобы генерировать действительно хороший машинный код и поднимать вещи во время выполнения. Для сравнения, Go имеет довольно простой компилятор, который в настоящее время не поднимает, не разворачивает и не генерирует действительно сжатый машинный код, поэтому неудивительно, что он проигрывает. Однако следует помнить, что время Java не учитывает время запуска JVM или то, сколько раз его нужно запустить, чтобы JVM правильно его JIT. Для долгосрочных программ это не актуально, но в некоторых случаях имеет значение.

Что касается остальных тестов, то Java и 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
Это именно тот ответ, на который я надеялся, спасибо!
Грег Слодкович
Гораздо меньше использования кода и памяти, компилируется в машинный код, лучше разработан. Все это берет на себя недостаток скорости.
Моше Рева
22
  1. Даже не говоря, какие проблемы были решены, весь эталон не имеет смысла.
  2. JVM и CLR используют JIT для создания машинного кода. Там нет причин, это должно быть медленнее. Это просто стоит вам возраст, чтобы загрузить.
  3. Go был разработан, чтобы строить быстро . У вас нет тонны времени компиляции и оптимизации времени загрузки. Go компилирует свою собственную стандартную библиотеку к моменту загрузки приложения Java.

Может ли Go быть быстрее во время выполнения? Да. Будет ли Go когда-нибудь быстрее во время выполнения? Я не знаю. Возможно, компиляторы добавят дополнительную оптимизацию за счет времени компиляции. Но я не думаю, что они заинтересованы в этом. Они работают в Google.
То, что они хотят, это язык, который позволяет быстро развиваться и хорошо выполняет то, что они делают. Черт, даже если бы этот тест был достоверным, это означало бы, что они вдвое быстрее C и в 14 раз быстрее Python. Это более чем достаточно.
Оборудование дешевое, код дорогой. Код становится больше и медленнее, когда вы инвестируете деньги, аппаратное обеспечение становится все дешевле и меньше. Вам нужен язык, который не требует 4 фреймворков и 2000 классов для выполнения чего-либо полезного.
В дизайне Go нет ничего, что делает его медленным. Однако дизайнерам Go присуще нечто, что делает его медленнее, чем сборка: здравый смысл.

back2dos
источник
1
Большинство (все?) JIT компилируются во время выполнения, а не при первой загрузке кода. Этот машинный код может вообще не генерироваться для некоторого кода и также может быть легко признан недействительным, например, если у objsin каждый раз for (obj : objs) { obj.meth() }разные реализации methи JIT пытается встроить его. Конечно, все это на самом деле является преимуществом в обычных случаях, но все же заслуживает внимания.
@delnan: V8 JITs любой код перед его выполнением. Кроме того, LLVM был построен с учетом JITting, поэтому (с некоторыми усилиями, конечно) вы можете выполнить любую оптимизацию вовремя, что в противном случае произошло бы во время компиляции. Однако некоторые оптимизации, такие как escape-анализ, действительно работают только с JIT.
back2dos
3
>> Даже не говоря, какие проблемы были решены << Посмотрите, и вы обнаружите, что эти веб-страницы действительно говорят, какие проблемы были решены. На самом деле, вы найдете исходный код программы, команду сборки, команды запуска, версию реализации языка, я да я да я
igouy
10

Я также заметил, что в тесте regex-dn Go был особенно медленным . Расс Кокс объяснил, почему Go не был таким результативным в этом конкретном тесте . Причина в том, что пакет regexp в Go использует другой алгоритм сопоставления, который плохо работает в этом конкретном тесте, но может быть на несколько быстрее в других тестах. Также Ruby, Python и другие языки сценариев используют реализацию C другого алгоритма сопоставления регулярных выражений .

И, наконец, игра « Тесты компьютерных языков» состоит из микропроцессоров, которые могут не совсем точно отражать многие характеристики измеряемых языков и даже приводить к ошибочным впечатлениям. Этот исследовательский документ, недавно опубликованный Google, дает более точный обзор некоторых языковых характеристик Go, Scala, Java и C ++, в частности, части «V. Performance Performance». Таким образом, в конце концов Go почти так же требователен к памяти, как и Java (81% памяти Java), и потребляет на 170% больше памяти, чем Scala (не удалось найти в статье информацию о том, рассматривалось ли потребление памяти JVM).

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

Alex
источник
3
>> Это исследование, недавно опубликованное Google << Это не исследование, и оно не было опубликовано Google. Это отчет одного из сотрудников Google, представленный на семинаре Scala Days 2011 в Scala.
igouy
>> может не совсем точно отражать многие характеристики измеряемых языков и даже приводить к ошибочным впечатлениям << Это так же верно для программ «распознавания петель» и, вероятно, справедливо для любого сравнения производительности между различными языками программирования. Фактически, автор говорит вам: «Мы не исследуем какие-либо аспекты многопоточности или механизмы типов более высокого уровня ... мы также не выполняем тяжелые числовые вычисления ...»
Игуей
@igouy На обложке вы можете прочитать «Google», а все, что уместно, покрыто соответствующими ссылками. Так почему же это не «исследовательская статья, опубликованная Google», если Google упоминается с адресом штаб-квартиры? Исследовательские работы не являются областью только для научных кругов.
Алекс
На обложке вы можете прочитать почтовый адрес, по которому с автором можно связаться, и адрес электронной почты автора. Проверьте URL-адрес PDF-файла, который вы разместили. Обратите внимание на домен - days2011.scala-lang.org - семинар Scala Days 2011 "Scala.
igouy
1

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

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

Мило Бэнкс
источник
4
Это 8-летний вопрос, и дешевые вычислительные мощности сделали его в значительной степени неуместным. Ваш ответ также основан на «ваших чувствах», а не на твердых данных. Я не хочу вас обескураживать, но ...
Каяман