Может ли кто-нибудь количественно оценить разницу в производительности между C++ и Java?

До JIT изначально Java была медленной, но сегодня производительность довольно близка к C++. Я хочу знать, проводил ли кто-нибудь измеримое сравнение производительности между двумя языками? Чем Java уступает C++? Java обеспечивает значительный прирост производительности для разработчиков, поэтому они могут писать приложения намного быстрее из-за мусорного колледжа, отсутствия указателей и т.д. 100% Java, возможно, в два раза, но разработчики по-прежнему выбирают C / C++ из соображений производительности. Может ли кто-нибудь продемонстрировать, где нельзя заставить Java работать так же хорошо, как C++ для приложений, подобных тем, о которых я упоминал.

Позвольте мне просто добавить, что большая часть работы с приложениями все еще выполняется на C++ по определенной причине. Это более чем субъективный вопрос. Языки с более высоким уровнем абстракции часто снижают производительность. Если бы этого наказания не существовало, мы бы все программировали на языках более высокого уровня. Чем все еще выгодна Java по сравнению с C++? Быть конкретной.

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

1800 INFORMATION 24.11.2008 08:37

Может быть, это немного отвлекает, но ... «Основные проблемы нашей работы не столько технологические, сколько социологические по своей природе» -Peopleware. «Мой язык быстрее твоего» будет продолжаться до скончания веков. Я бы предпочел спросить ... что разработчикам наиболее удобно и будет ли этого достаточно?

Gishu 24.11.2008 09:21

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

Sandman 24.11.2008 12:13

Я думал, что к субъективным и аргументированным вопросам относятся неодобрительно? Мне кажется, ОП уже решил, что Java лучше. В любом случае, как бы вы не хотели это признавать, производительность и надежность повышаются с обеих сторон. Управление ресурсами на Java без надлежащего RAII - это боль.

jalf 24.11.2008 13:02

Джальф, я выделил вопрос жирным шрифтом. Я решил, что Java медленнее, чем C++, по крайней мере, текущая реализация. Теперь вопрос в том, почему.

anon 26.11.2008 04:33
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
16
5
4 095
13
Перейти к ответу Данный вопрос помечен как решенный

Ответы 13

Во многом это похоже на сравнение яблок с апельсинами.

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

Java не дает вам такой свободы. Он дает вам функции, которые вам, возможно, даже не нужны. Как бы то ни было, вы можете захотеть выделить память самостоятельно, вам придется использовать объекты кучи для всего, поэтому вы получите влияние на сборку мусора.

Как только вы начнете говорить о графических интерфейсах, сравнение станет еще более трудным, поскольку разные инфраструктуры пользовательского интерфейса и наборы инструментов имеют разные проблемы с производительностью. Например, Swing / AWT обычно будет медленнее, чем что-то, написанное непосредственно для собственной ОС. В C++ вы редко найдете действительно переносимый инструментарий и т. д.

Я думаю, что когда разработчики начали openoffice, Java была намного медленнее, а инструменты пользовательского интерфейса были медленными и некрасивыми. Такие инструменты, как Eclipse, доказывают, что вы можете создавать относительно хорошие пользовательские интерфейсы даже на Java, хотя, по общему признанию, SWT - это набор инструментов, который делает много вещей на нативном уровне.

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

Barry Kelly 24.11.2008 08:30

Если у вас нет типов, которые вряд ли дадут вам возможность самостоятельно управлять памятью, не так ли?

1800 INFORMATION 24.11.2008 10:45

Барри, я имел в виду выделить объекты ... Не уверен, что вы действительно можете сделать с просто старым добрым массивом ...

Uri 24.11.2008 12:14

Я не верю, что кто-то сможет доказать, что C++ всегда будет значительно быстрее, чем Java, по той простой причине, что вы всегда можете вернуться к JNI, чтобы получить собственную скорость от Java.

См., Например, SWT - графические инструменты, созданные IBM (я думаю), предназначенные для замены Swing и обеспечения как собственной производительности, так и внешнего вида.

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

C++ всегда будет быстрее C++?

Eran Galperin 24.11.2008 08:04

Хорошая уловка, сейчас исправлено, но, по крайней мере, вы не могли придраться к правдивости утверждения :-)

paxdiablo 24.11.2008 08:06

Потому что, как только вы это прочитали, его производительность увеличилась на единицу? :)

Uri 24.11.2008 08:15

Чтобы завершить ответ Пакса и Ури, вот несколько тестов недавний:

Как уже говорилось, это два очень разных языка, и некоторые убеждены, что Java когда-нибудь будет медленнее C++ из-за:

  • Выделение кучи для объектов все (даже небольших, таких как итераторы)
  • множество динамических отливок
  • увеличенное использование памяти

[Юмор]

"Java is high performance. By high performance we mean adequate. By adequate we mean slow." Mr. Bunny

Как упоминалось дрибес в комментариях, выделение кучи не является хорошим аргументом. В этом "Легенды городского перформанса, заново" упоминается:

"Garbage collection will never be as efficient as direct memory management." And, in a way, those statements are right -- dynamic memory management is not as fast -- it's often considerably faster.
The malloc/free approach deals with blocks of memory one at a time, whereas the garbage collection approach tends to deal with memory management in large batches, yielding more opportunities for optimization (at the cost of some loss in predictability).

- Выделение памяти в Java почти бесплатное (около 10 машинных инструкций), и сборщик мусора требует затрат только на живые объекты, поэтому первый пункт неверен.

David Rodríguez - dribeas 24.11.2008 11:22

Люди не должны спорить о вещах, которых они не знают. Распределение кучи, динамическое приведение ... Очень документированный и очень объективный ответ. Это иронично.

Gilles 24.11.2008 12:12

dribeas: Все не так просто. 10 инструкций, а что дальше? Все ваши объекты волшебным образом собраны в сборку мусора? Как насчет накладных расходов, необходимых для обеспечения возможности сборки мусора? Объекты должны хранить больше данных, что удорожает их инициализацию, что-то должно определять, когда запускать сборщик мусора и так далее.

jalf 24.11.2008 12:39

@Jalf: Конечно. Ограничения Java GC являются причиной того, что он работает в 17 раз медленнее, чем F# в этом тесте: fsharpnews.blogspot.com/2010/05/java-vs-f.html

J D 02.07.2010 03:26

Я провел собственное сравнение производительности: edval.biz/benchmarking-java-versus-c-with-astar на небольшой, но все же значительной программе, загружающей процессор. Удивительно, но я обнаружил, что Java на 30% быстрее. Поскольку я давно фанат C++ и эксперт по C++, я очень старался изменить результаты. Однако после довольно всесторонних экспериментов я считаю, что Java работает быстрее. Причина может заключаться в неспособности оптимизирующих компиляторов C++ предполагать «отсутствие псевдонимов». Если вы мне не верите, скачайте мой исходный код или попробуйте сами.

Tim Cooper 20.07.2010 09:58

Для меня этот вопрос - отвлекающий маневр (возможно, не намеренно). Это действительно неправильный вопрос.

Первые вопросы, которые нужно задать, - это

  1. Что замедляет мою программу?
  2. Каковы основные соображения при проектировании производительности для моей новой программы?

Вот несколько хороших вопросов "почему"

  • Слишком много ненужных операций ввода-вывода?
  • Используется слишком много памяти?
  • Неисправен ли распределитель памяти (слишком много выделений, слишком много мелкозернистых объектов)
  • Моя программа заблокирована при вводе-выводе по сети на длительное время
  • У меня замки не в том месте

Я подозреваю, что вам действительно нужно сначала сосредоточиться на аспектах пerformance вашей программы (с большой буквы), а не на аспектах пerformance (маленькая буква «p»). Если вы можете добраться до точки, где язык мешает, значит, вы проделали действительно хорошую работу в отношении производительности.

Для нового кода - важно заранее спланировать производительность и эффективность. Я всегда рекомендую, чтобы производительность и эффективность рассматривались так же, как и любая другая функция (они являются функциями): так же, как UI bling или надежность. Конечно это будет зависеть от многих вещей, но когда это важно, вам нужно спланировать это заранее:

  • Выберите структуры данных и алгоритмы, подходящие для набора данных и ожидаемого масштабирования.
  • Многопоточные приложения на основе пользовательского интерфейса там, где это необходимо (поток пользовательского интерфейса, фоновый поток / поток обработки)
  • Строить планы для длительных задержек сетевого ввода-вывода
  • Строить планы для постановки целей и измерения производительности заранее - регулярно запускайте регрессионные тесты
  • Измерьте использование памяти - пожиратели памяти работают медленно (пусть начнутся шутки :))
  • Не опрашивайте, когда есть события, обратные вызовы или другие механизмы уведомления

Причина, по которой я думаю, что это отвлекающий маневр, заключается в том, что редко можно просто выбирать между C++ и Java - это очень, очень разные языки с очень разным временем выполнения. Я подозреваю, что обычно у вас есть другие ограничения, которые так или иначе подталкивают вас - это будут факторы более высокого порядка, чем производительность языка. Вычислимость с существующим кодом, навыки и опыт существующих сотрудников и т. д. И т. Д.

Окружающая среда тоже имеет значение. Например, Java почти никогда не будет правильным выбором для клиентских приложений (в отличие от веб-приложений). И наоборот, нативный C++ почти никогда не станет выбором для веб-приложений. (обратите внимание, я парень, работающий с окнами - в * nix ситуация может быть очень другой).

Ответ принят как подходящий

Компиляторы JIT могут работать быстрее для многих отдельных конструкций кода, поскольку они могут использовать профилирование кода во время выполнения.

Например, VonC в своем ответе на этот вопрос упоминает выделение кучи для всех объектов. На самом деле это не так: JIT может размещать объекты в стеке, если он может доказать с помощью анализ побега, что ссылки на объект не переживут кадр стека. Таким образом, компилятор может получить преимущество в производительности за счет выделения стека, в то время как программист может быть уверен в безопасности предполагаемого выделения кучи GC.

Точно так же Ури упоминает виртуальные функции (называемые виртуальными методами в большинстве языков, отличных от C++). Это еще один случай, когда у JIT-компиляторов есть преимущество, которое почти никогда не доступно для опережающих компиляторов (AOT): JIT может вставить встроенную проверку дешевого типа (сравнение разыменованных слов) и фактически встроить вызов виртуального метода, если этот конкретный сайт вызова оказывается мономорфным (т.е. на практике фактический тип всегда один и тот же). Оказывается, что на практике до 95% всех вызовов виртуальных методов являются мономорфными, так что это может быть довольно большой выигрыш - и это выигрыш, которым сложно воспользоваться компиляторам AOT, поскольку загрузка кода времени выполнения может динамически изменять характеристики времени выполнения.

Это 80% число составлено? Я предполагаю, что если бы оно было действительно таким высоким, кодер использовал бы виртуальные функции для вещей, для которых они не должны использоваться ...

Greg Rogers 24.11.2008 09:08

Нет, это не так. Я получил его от Azul's Cliff Click (ранее Sun и архитектор сервера HotSpot). Я добавил ссылку на атрибуцию - ищи цифру 95% (на самом деле она была выше, чем я запомнил).

Barry Kelly 24.11.2008 09:18

Обратите внимание, что он говорит о Java, которая по умолчанию использует виртуальные методы, то есть намного больше, чем большинство других статически типизированных языков (но по теме вопроса).

Barry Kelly 24.11.2008 09:41

Теоретически, в зависимости от того, как среда выполнения C++ реализует свой RTTI, можно было бы выполнять такую ​​же проверку поиска в кеше для всех виртуальных вызовов. Это не что-то особенное для JIT-компиляторов. Я неправильно понял принцип, описанный в вашем сообщении, но я определенно вижу, что это приносит пользу.

Greg Rogers 24.11.2008 09:43

Это не так просто, Грег. Подход, специфичный для Azul, использует толстые 64-битные указатели со встроенной информацией о классе, так что даже косвенное обращение не требуется. Точно так же он работает для динамически загружаемого кода, что является нетривиальным преимуществом для обслуживания в серверном коде.

Barry Kelly 24.11.2008 09:57

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

Barry Kelly 24.11.2008 09:58

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

erickson 24.11.2008 21:20
ibm.com/developerworks/java/library/j-jtp09275.html - «текущие сборки Mustang (Java SE 6) могут выполнять анализ выхода и преобразовывать выделение кучи в выделение стека (или отсутствие выделения), где это необходимо». Я не знаю последних подробностей, извините.
Barry Kelly 26.11.2008 16:11

Еще одна скамейка: перестрелка

За вас не проголосуют, потому что ваша ссылка доказывает, что Java медленнее, чем C++

1800 INFORMATION 24.11.2008 10:52

Java медленнее C++. Вот почему я задал вопрос. Теперь вопрос конкретно в том, где Java медленнее?

anon 26.11.2008 04:18

Некоторые вещи лучше строить с помощью Java, C# или любых языков управляемого программирования. В остальном всегда будет лучше строиться на неуправляемом языке программирования (например, C или C++).

Первая категория обычно включает «приложения» в целом, а вторая категория обычно включает «платформы» в целом.

Создание FireFox или WebKit на Java не только просто глупо, но и приведет к тому, что конечный продукт станет действительно очень медленным, плохим и потратит много ресурсов для конечных пользователей. Open Office, возможно, является хорошим кандидатом для Java, C# или Болтовня в этом отношении. Но создавать FireFox или WebKit на Java (или C#, если на то пошло) просто глупо и является гарантией отказа ...

C++ и C будут на несколько порядков быстрее для многих вещей, кроме того, они будут использовать часть памяти. Просто так оно и есть. И пока Java и C# являются «управляемыми» языками программирования, это никогда не изменится. Может быть, когда-нибудь процессоры станут настолько быстрыми, что «это не имеет значения». Но я сомневаюсь в этом, поскольку люди склонны сгибать свои требования по мере увеличения количества ЦП ...

Если вы хотите создать браузер, извините, но вам нужно научиться C или C++;)

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

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

Производительность программы зависит от трех вещей: компилятора, базовой платформы / оборудования и самого программного кода.

Не «язык». Самое близкое, что вы получаете, - это компилятор.

Есть веские причины, по которым один из языков может быть быстрее другого. C++ дает меньше обещаний, которые потенциально могут замедлить выполнение программы, но Java JIT'ed, что означает, что он потенциально может использовать информацию времени выполнения для оптимизации кода, что C++ не может легко сделать ... И опять же, нигде в в спецификации говорится, что C++ должен быть изменен нет. Точно так же, как я считаю, есть также компиляторы Java, которые генерируют собственный код вместо байт-кода JVM.

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

Сборка мусора - еще один замечательный пример. Конечно, сборка мусора подразумевает некоторые накладные расходы, но также позволяет использовать некоторые важные ярлыки. Выделение кучи смехотворно дешево в управляемых языках, таких как Java или .NET, потому что управляется и собирает мусор. В C++ это… не указано, конечно, но на практике обычно очень медленно, потому что ОС должна пройти через кучу, чтобы найти свободный блок памяти в более или менее фрагментированном пространстве памяти. Какой самый быстрый? Зависит от ОС. Зависит от компилятора. Зависит от исходного кода.

Исходный код также имеет большое значение. Если вы возьмете программу на Java и наивно перенесете ее на C++, она будет работать как дерьмо. C++ не так хорошо справляется с виртуальными функциями и обычно предлагает лучшие альтернативы, которые вы могли бы использовать вместо этого. Выделение кучи может быть очень медленным в C++, поэтому, опять же, наивное повторное выполнение программы Java было бы крайне неэффективным. То же самое и в обратном направлении. Многие идиомы C++ были бы излишне медленными при прямом переносе на Java. Итак, даже если вы остановились на одной платформе и одном компиляторе, как вы сравните производительность своей программы? Чтобы даже передать его компилятору, вам нужно написать две его реализации, и тогда это уже будет не та же программа.

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

Думаю, самый краткий ответ на ваш вопрос - «Нет. Никто не может количественно оценить разницу в производительности между C++ и Java»;)

+1, я писал ответ в этих строках, но не близко к этому сообщению

David Rodríguez - dribeas 24.11.2008 12:38

Очень хороший! Хотя я не совсем согласен, я все же поставил ему +1;)

Thomas Hansen 24.11.2008 21:12

+2 за ответ, -1 за преувеличения насчет кучи и виртуальных функций C++ = +1

Marcin 24.11.2008 22:22

Это не преувеличение. Куча работает очень медленно по сравнению, скажем, с кучей .NET (которая, по сути, представляет собой просто операцию проталкивания в стек. Распределение кучи C++ может включать в себя переключение контекста, а также обход связанного списка. Это может быть несколько порядков величины. помедленнее.

jalf 24.11.2008 23:18

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

jalf 24.11.2008 23:22

-1: Все знают, что сложно делать общие выводы о производительности Java и C++ по всем программам, но меня расстраивает то, как люди перестают пытаться. Это простой вопрос, и многим людям нужно получить какие-то рекомендации по этому вопросу. На самых популярных компиляторах / платформах, на больших программах, включающих множество алгоритмов, что является хорошим практическим правилом или, по крайней мере, набором точек данных (т. Е. Тестов)?

Tim Cooper 20.07.2010 10:04

Настоящим я делаю запись: я считаю, что независимые тесты на популярных платформах показывают, что Java примерно в два раза медленнее, чем C++, в больших программах. В небольших программах (микробенчмарках) Java все еще в среднем в два раза медленнее, но с очень большими вариациями.

Tim Cooper 26.07.2010 06:25

@ Тим: Речь идет не об обобщении производительности по всем программам, а по всем программам, компиляторам и компьютерам. И дело не в том, чтобы «сдаться», а в том, чтобы понять, что ответ бесполезен, и нет простого хорошего практического правила.

jalf 26.07.2010 16:18

Я думаю, что в реальном мире (реальные приложения делают реальные вещи) хорошо написанный C / C++ превосходит управляемые языки. Да, это правда, теоретически распределение кучи в gc обходится дешево. Однако грамотный разработчик C++ не стал бы все складывать в кучу!

seand 18.08.2010 10:11

+1: Хорошее объяснение языкового сравнения в целом; -1: Куча в C / C++ управляется в пользовательском пространстве, поэтому она так же эффективна, как и куча Java; -1: вызов виртуальных функций в C++ выполняется так же быстро, как и использование указателя на функцию. Кроме того, вызывающие программы также встроены в большинство оптимизирующих компиляторов, поэтому Java может работать не лучше, чем C++, и обычно медленнее.

user283145 24.08.2010 14:58

Куча в C++ не сжимается, как в Java / .NET, а это означает, что найти блоки памяти для выделения намного дороже. Виртуальные функции примерно так же дороги, как указатели на функции, да (на самом деле, есть еще один уровень косвенного обращения к виртуальным функциям, но он достаточно близок), но я никогда не говорил, что указатели на функции также работают быстро.

jalf 24.08.2010 15:17

А в C++ виртуальные функции часто встроены в нет, потому что во время компиляции обычно трудно увидеть, какая функция будет вызвана (если бы можно было вызвать только одну функцию, вы, вероятно, не сделали бы функцию виртуальной). И да, Java может быть быстрее C++. Так что же -1;) почему так много программистов считают религиозным вопросом: «С ++ всегда должен быть самым быстрым, верно? Верно?

jalf 24.08.2010 15:18

Некоторые моменты, которые следует учитывать:

  • Если вы получите лучший компилятор C++, ваш код не станет быстрее. Сначала вам нужно перекомпилировать его. Если вы получите лучшую JVM, весь ваш Java-код будет работать быстрее

  • Если вы получите лучший компилятор C++ / JVM, вы увидите на 10-20% более быстрое выполнение, обычно в крайних случаях. Если вы найдете лучший алгоритм для достижения того, что вам нужно, вы легко сможете получить на 1000-10 000% больше производительности, а иногда даже больше.

Итак, сегодня, если производительность является проблемой, вам следует обратить внимание на эти два факта:

  • Насколько легко язык позволяет заменить один алгоритм другим? (он же «Рефакторинг»)
  • Насколько быстро вы можете писать на нем код?

Все остальное - просто FUD.

Многие забывают, что методы JIT можно применять к любым двоичным файлам, даже к тем, которые создаются компилятором C++. Большинство преимуществ JIT-компиляции для Java также справедливы для C++, если вы используете что-то вроде HP Dynamo (эмулятор, который запускает исполняемые файлы быстрее, чем собственный чип, на котором он работает и эмулирует). Профилирование времени выполнения на самом деле является преимуществом не Java в производительности, а JIT-компиляции в целом.

Я реализовал чувствительные к производительности приложения (физическое моделирование, финансовые модели) как на C, так и на Java. Реальность такова, что я всегда получал гораздо больший выигрыш в производительности за счет изменения алгоритмов, чем за счет настройки реализации, но реализация также имеет значение. На данный момент я считаю, что Java работает медленнее, чем C (у меня нет такого большого опыта работы с числами в C++), но многое можно получить путем тщательной настройки, и эта настройка намного проще в Java, поскольку вы не нужно иметь дело с ошибками сегментации, двойным освобождением и т. д. C++ занимает здесь среднее место, поскольку современные методы C++ (интеллектуальные указатели, шаблоны, контейнеры STL) предлагают как скорость, так и относительную безопасность использования.

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

Хорошо известно, что когда приложение Java запускается впервые, оно должно активировать свой конденсатор потока, чтобы вернуть среду в состояние 1995 года. Это вносит небольшую задержку при запуске. Но как только это закончится, JVM будет работать примерно так же, как сопоставимая программа C++, работающая на оборудовании с 1995 года.

Where does Java fall short when compared to C++?

Отличный вопрос. Java и JVM имеют два основных недостатка, снижающих производительность по сравнению с C++:

  • Обобщения, основанные на стирании типа.

  • Отсутствие ценностных типов.

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

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

Обе эти проблемы в совокупности делают невозможным реализацию эффективной общей хеш-таблицы в Java. В частности, .NET решила обе эти проблемы. Например, Общая хеш-таблица Java может быть в 17 раз медленнее, чем .NET Dictionary.

Кроме того, JVM имеют очень медленные FFI по сравнению с C++. Я слышал, что простой вызов внешней функции C из Java может занять 1000 циклов.

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

mikera 17.03.2012 17:11

@mikera: По сравнению с C++, да. Вот почему .NET специализируется только на типах значений и сохраняет общий код над общими ссылочными типами во время выполнения. Это обеспечивает хороший компромисс с несколькими специализированными классами и без накладных расходов, когда это действительно важно (не ссылочные значения).

J D 19.03.2012 03:30

Другие вопросы по теме