Подтвердить что ты не робот

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

Java была первоначально медленной до JIT, но сегодня производительность довольно близка к С++. Я хочу знать, выполнил ли кто-нибудь измеримые сопоставления производительности между двумя языками? Где Java отстает по сравнению с С++? Java предоставляет множество преимуществ производительности разработчикам, поэтому они могут быстрее писать приложения из-за колледжа мусора, отсутствия указателей и т.д. Такие приложения, как Firefox, Webkit и Open Например, офис может быть разработан гораздо быстрее и надежнее, если он написан на 100% Java, возможно, в 2 раза, но разработчики по-прежнему выбирают C/С++ по соображениям производительности. Может кто-то продемонстрировать, где Java не может быть выполнен так же, как и С++ для приложений, подобных тем, о которых я говорил.

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

Языки не имеют скорости. Спецификации языка Java или С++ не указывают "и программы должны быть скомпилированы так, чтобы быть эффективными".

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

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

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

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

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

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

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

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

Я думаю, самый краткий ответ на ваш вопрос: "Нет. Никто не может количественно оценить различия в производительности между С++ и Java";)

Ответ 3

Чтобы завершить Pax и Uri ответ, вот несколько недавних тестов:

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

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

[Юмор]

"Java - это высокая производительность. По высокой производительности мы имеем в виду адекватную. Под адекватным мы подразумеваем медленный". Mr. Банни

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

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

Ответ 5

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

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

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

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

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

Ответ 6

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

Ответ 7

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

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

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

Вот некоторые полезные "почему" вопросы

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

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

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

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

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

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

Ответ 8

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

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

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

Ответ 9

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

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

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

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

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

Все остальное - это только FUD.

Ответ 10

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

Ответ 11

Где Java отстает по сравнению с С++?

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

  • Генерики, основанные на стирании стилей.

  • Отсутствие типов значений.

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

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

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

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

Ответ 12

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

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

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

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

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

Ответ 13

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

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