Что быстрее java или c
Перейти к содержимому

Что быстрее java или c

Может ли Java быть быстрее C++?

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

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

Для начала несколько “дано”:

  • Мы сравниваем С++ 2011, компилируемый в машинный код, и обычную Java 7 (не real-time, embedded или что-то в этом роде), компилируемую в JVM-код, который только в процессе выполнения будет налету через JIT тоже компилироваться в машинный код.
  • Допустим, компиляторы C++ и Java генерируют максимально эффективный код, насколько семантика языка позволяет оптимизировать.

Положим, A – это линейная скорость выполнения машинного когда. B – скорость компиляции байт-кода JVM в машинный код. Тогда общая скорость выполнения кода:

Очевидно, что B1 = 0 , так как С++ генерирует машинный код напрямую и не требует дополнительной работы в процессы выполнения. Но B2 стопроцентно НЕ ноль, так как каким бы эффективным не был компилятор JIT, он ВСЕГДА требует какого-то времени для компиляцию. Более того, JIT не компилирует все сразу, а “подкомпилирует” по мере прохождения путей выполнения. Получается, всегда есть ненулевая вероятность, что неожиданно придется выполнить код, ранее не требуемый, и потребуется время на его компиляцию. Даже если предположить, что компилятор JIT применяет изощренные способы предсказания путей выполнения и делает все, чтобы уменьшить B2 , но B2 по определению не 0. Если был бы 0, то не было бы JVM, а был бы чистый машинный код.

Далее, рассмотрим A1 и A2 . Эти параметры определяют, насколько эффективно компилятор создает код (или байт-код). По моему личному, субъективному и предвзятому мнению, у С++ (не С) больше шансов на оптимизацию благодаря шаблонам (компилятор имеет полноценную семантическую информацию для проведения inline’а) и генерация машинного кода под конкретную платформу (компилятор точно знает, какие машинные инструкции были бы максимально эффективны в каждом случае). Увы, я не особо силен в generic’ах Java, и руководствуюсь только слухами, что в Java они “ненастоящие”, добавленные гораздо позже и уступающие шаблонам C++. И так как компилятор обязан выдать стандартный переносимый JVM-код, то нет возможности оптимизировать под конкретную платформу. Есть надежда, что это сделает JIT, но там уже не будет семантической информации для более глубокой оптимизации. А еще JIT должен быть быстр, то есть будет компромисс между качеством оптимизации и скоростью компиляции. В С++ такой проблемы нет, так как компилировать можно как угодно долго.

Итак, это мои доводы для меня самого, измеренные в виртуальных попугаях. Не получается у меня убедить самого себя, что Java может быть быстрее или хотя бы на уровне с С++ по скорости. Буду рад за помощь в понимании этого вопроса.

Мы со Стасом проводили несколько несложных сравнений, в основном на реализации QuickSort, и Java по линейной скорости кода проигрывала где-то на 10%.

До C++ 2011 можно было говорить, у С++ нет модели памяти и стандартной библиотеки для потоков, поэтому у Java есть шанс выиграть на многопоточности, но сейчас у С++ все на месте. А подходы к многопоточности у С++ и Java, как мне кажется, одинаково неудобные (хотя std::async() – это очень сильная возможность), и им обоим далеко до goroutines в Go, actor’ов в Scala и т.д.

Понятно, что 10% не всегда делают погоду. Иногда важнее развитые инструменты интроспекции, среды разработки, контролируемое выполнение, замена кода налету и много другое, что дает платформа Java, и не дает “молотилка” C++. Но зачем говорить про скорость то?

Производительность C++ vs. Java vs. PHP vs. Python. Тест «в лоб»

/update/ Статья обновлена по результатам обсуждения. Поправлен код Python (около 40% ускорения), написан код на Perl и Ruby (но меня терзают смутные сомнения, что с ruby я что-то сделал неправитьно), поправлен код на Java (на моей машине корректнее тестировать int, а не long. к тому же int в Java эквивалентен long в C++).

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

После прочтения очередной статьи мне захотелось самому разобраться «здесь и сейчас». Сначала захотелось сравнить Java и C++ (не верил я, что в вычислительных тестах ява может догнать и обогнать cpp). 10 минут и простой код на C++ и яве готов: простой цикл и математические операции. После написания теста подумал и перевёл их на php и python. Позже добавился код на perl и ruby.

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

1) Мне нравится ява и я честно предполагал, что результаты будут лучше. Обновлено: long в 64-х битных системах работает значительно быстрее. При работе с int в 32-х битных системах Java значительно ускоряется (на моей машине быстрее, чем C++, видимо, JVM оптимизирует исполнение по умолчанию)
2) Я догадывался, что php будет медленней C++ и Java, но не думал, что он окажется быстрее Perl.
3) Предполагал, что Python будет сопоставим с PHP, но ошибся. Видимо, стандартная поставка PHP лучше оптимизирует исполнение кода.
4) Я совсем не знаком с Ruby, код взят из одного из комментариев. Причём использован код 1, так как у меня он работает быстрее чем код 2. Возможно, это также связано с тем, что у меня 32bit-система.
5) Я достаточно уважительно отношусь к различным языкам программирования, эта статья ни одним из углов не нацелена на разжигание холиваров. Каждый язык имеет свою нишу и своих поклонников.

Тесты запускались по 5 раз минимум, чтобы избежать случайных всплесков. Запускались из консоли и как «nice -n -9», то есть с максимальным на данный момент приоритетом в системе.

Чтобы не заставлять вас читать всю статью, сразу приведу краткие результаты.

Диаграмма (обновленная):

Старый вариант здесь
На диаграмме слолбец с Ruby частично прозрачен по причине того, что на моей машине скрипт Ruby исполнялся неприлично долго, в то время как в комментарии указано, что скрипт исполняется в 4 раза быстрее скрипта на Python — я в замешательстве.
Столбец с Python прозрачен, так как при включении psyco скрипт ускоряется более чем в 10 раз. Проверил на своей машине. Но это, с моей точки зрения, хак, не отражающий собственную производительность языка.
Столбец с PERL, как могут заметить старожилы, теперь идёт вровень с Python 2.6. Причиной этому послужила смена кода с C-подобного синтаксиса на использование range. Дополнительную производительность (около 12%) можно получить использовав директиву «use integer;», но это, по-моему, тоже хак.

Добавлен столбец с запуском Java-кода с ключём «-server». После перехода с «long» на «int» (повторюсь, int в java такой же как и long в c++ на 32bit-arch) он начал давать прирост в производительности почти вдвое.
Столбец с Ruby 1.9 на моём железе не тестировался, результат перенесён через сравнение с производительностью Python’а на той же машине.

И, чтобы не быть голословным, тестовый код.

Java, Test01.java (int в Java то же что и long в C++):

Python, Test01.py (вынос кода в функцию ускоряет работу кода почти вдвое, отдельная же инициализация range() на моей машине даёт порядка 5% производительности):

Perl, Test01.pl (обновлено, с range работает на 25% быстрее против c-подобного синтаксиса for):

Вот здесь приведён красивый пример на Perl, но, мне кажется, такой вариант уже слишком специфичен.

Вот здесь в комментариях обсуждают решение на erlang.

Как видите, ничего сложного: два цикла и математическое выражение. Вычислительная задача в чистом виде.

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

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

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

Когда Java быстрее C++ — сравнение производительности

Статья "Java vs C++ "Shootout" Revisited" опровергает бытующее мнение о низкой производительности Java-приложений. Приводятся результаты сравнения производительности, в котором на некоторых тестах Java ( Sun Java 1.4.2_01 ) выигрывает по скорости у C++ (GCC 3.3.1).

Re: Когда Java быстрее C++ — сравнение производительности

Нечем тут гордится что на C++ писать не умеют !

Re: Когда Java быстрее C++ — сравнение производительности

Абсолютно не объективный тест. Где соотношение количества ресурсов, которые отжирают для этих целей хоть клиентские, хоть серверные приложения java в сравнении с приложениями, закодированными на c++? опкод всегда будет быстрее java и это факт.

Re: Когда Java быстрее C++ — сравнение производительности

Гы гы гы. Оптимизированно написаный Java код работает быстрее чем неоптимально написаный C++ код :-). Реально мужик доказал только то, что человек, который умеет писать нормальный код. может этот код сделать быстрым :-). вне зависимости от платформы :-).

Re: Когда Java быстрее C++ — сравнение производительности

Если при кодировании после каждой строчки кода ставить строку for ( int i = 0 ; i < 65535; i ++); только тогда ява будет быстрее :)))

Re: Re: Когда Java быстрее C++ — сравнение производительности

> опкод всегда будет быстрее java и это факт. Ошибка ;-). Например вызов метода (особенно виртуального) в Java будет быстрее :-). Или например работа с RTTI в C++ на некоторых компиляторах может дать хорошую потерю производительности, а на Java все будет тип-топ :-). Много примеров, но суть в том, что дядька спец по Java, а вот в C++ он не шарит ;-).

Re: Когда Java быстрее C++ — сравнение производительности

Нда, на синтетических тестах действительно бывают такие приколы.

Re: Re: Когда Java быстрее C++ — сравнение производительности

>Если при кодировании после каждой строчки кода ставить строку for ( int i = 0 ; i < 65535; i ++); только тогда ява будет быстрее :)))

Только в том случае, если компилятор эту строчку не оптимизирует)

Re: Когда Java быстрее C++ — сравнение производительности

IMHO нюанс не в качестве кода, а в сборке мусора. С++ вызывает сборщик мусора для обьекта сразу, как тот перстал существовать. Java — как в голову придет.

В остальном код на C++ много эффективнее. Осталось придумать задачу, где требуется серьезная работа для сборщика мусора и С++ начнет проигрывать.

Re: Когда Java быстрее C++ — сравнение производительности

токо вот вопрос. а кто же писал оракловый инсталятор? И чего же он так тормозит? Может лохи писали? (хотя еще не проверял как работают проги под novm java, но думаю чудес не предвидится)

Re: Re: Когда Java быстрее C++ — сравнение производительности

А кто писал KDE? Чего оно тогда так тормозит (особенно при загрузке)?

Re: Re: Когда Java быстрее C++ — сравнение производительности

>С++ вызывает сборщик мусора для обьекта сразу, как тот перстал
>существовать.
Похоже я от жизни отстал. В какой из реализаций C++ появился garbage collector?

Re: Когда Java быстрее C++ — сравнение производительности

Статейка из разряда "На каких этапах наши паровозы быстрее гоночных болидов".Дурилка для маркетологов. Блин когдаж здохнет наконец этат утопия.

Re: Re: Re: Когда Java быстрее C++ — сравнение производительности

верятно имелись ввиду деструкторы

а вот по поводу КДЕ. Думаю, если такую весч напишут на Жаба. будет пипец.

Re: Re: Когда Java быстрее C++ — сравнение производительности

> Блин когдаж здохнет наконец этат утопия.
Никогда. Ибо не утопия это, а весьма хорошая платформа :-).

Re: Re: Re: Re: Когда Java быстрее C++ — сравнение производительности

> а вот по поводу КДЕ. Думаю, если такую весч напишут на Жаба. будет пипец.

Да ничего особенного не будет. Разницы ты не заметишь.

Re: Re: Re: Re: Когда Java быстрее C++ — сравнение производительности

>а вот по поводу КДЕ. Думаю, если такую весч напишут на Жаба. будет
>пипец.
Все будет нормально. Будет Java работать себе и память будет кушать. только что внизу оно будет на GTK или на QT написано. и все будет тип-топ.

Re: Когда Java быстрее C++ — сравнение производительности

Я не понимаю только одного, чтож вам Java как кость в горле? У неё своя ниша, свои задачи с которыми к слову говоря она прекрасно справляется. Мне вот у умников которые её ругают спросить хочется: а на чём они предлагают работать если нужна кроссплатформенность, серверная часть, не зависимость от БД? На С++ что ли? Или на Перле с Питоном? Давайте не будем бредить. То что Жава от релиза к релизу становится всё быстрее и удобнее по моему это всем на руку.

Re: Re: Re: Когда Java быстрее C++ — сравнение производительности

>>В какой из реализаций C++ появился garbage collector

ИМЗО имелось в виду освобождение памяти после того, как объект выходит из зоны видимости

Re: Когда Java быстрее C++ — сравнение производительности

> в котором на некоторых тестах Java ( Sun Java 1.4.2_01 ) выигрывает по скорости у C++ (GCC 3.3.1).

Нда, выбрали самый быстрый компилятор, да уж — ветку 3.4X пробовать не захотели.

Если сравнивать на тех областях, где либы явы быстрее, то тогда конечно. Тест совершенно не обоснованный и бессмысленный — пиар.

Re: Re: Re: Когда Java быстрее C++ — сравнение производительности

>>С++ вызывает сборщик мусора для обьекта сразу, как тот перстал
>>существовать.
>Похоже я от жизни отстал. В какой из реализаций C++ появился garbage
>collector?

Наверное, уважаемый eda вспоминал поговорку "чисто не там, где убирают, а там, где не мусорят" 🙂

Re: Re: Re: Re: Когда Java быстрее C++ — сравнение производительности

>ИМЗО имелось в виду освобождение памяти после того, как объект выходит
> из зоны видимости
Теперь остается только гадать :-).

Re: Re: Когда Java быстрее C++ — сравнение производительности

> Если при кодировании после каждой строчки кода ставить строку for ( int i = 0 ; i < 65535; i ++); только тогда ява будет быстрее :)))

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

Спецязыки для этого и делают — для применения в своей области. А Java вообще сразу писали для embedded system. нда. :)))))))

Re: Re: Когда Java быстрее C++ — сравнение производительности

У Ораклового инсталятора JDK "Oracle JDK 1.1.7.30o (JDK 1.1.7B based)", потому и тормозит.

Re: Re: Re: Re: Когда Java быстрее C++ — сравнение производительности

>Наверное, уважаемый eda вспоминал поговорку "чисто не там, где
>убирают, а там, где не мусорят" 🙂
Да да да ;-).

Re: Re: Когда Java быстрее C++ — сравнение производительности

ММММ не расчехлился. причем сборщтк мусора и С++ . Мусорщик — есть примочка ВМов. Хотя конечно если мусорщиком считать free() ?! То вряд ли гарбаж коллектор (мля слово то какое) тут вряд ли сие обскачет

Re: Re: Когда Java быстрее C++ — сравнение производительности

> IMHO нюанс не в качестве кода, а в сборке мусора. С++ вызывает сборщик мусора для обьекта сразу, как тот перстал существовать. Java — как в голову придет.

Это тоже верно — если сборщик ни разу не запустится, то потом система просто пометит память как пустую, одним махом, и скорость будет приличной :)))) Чем каждый раз вызывать деструктор, который объявлен например, но ничего не делает.

Re: Re: Re: Когда Java быстрее C++ — сравнение производительности

> Это тоже верно — если сборщик ни разу не запустится, то потом система просто пометит память как пустую, одним махом

"Потом" — это после выключения компьютера чтоли 🙂 ?

Re: Re: Re: Re: Когда Java быстрее C++ — сравнение производительности

> "Потом" — это после выключения компьютера чтоли 🙂 ?

В самую точку! После завершения работы программы — когда VM выключат :))))

Re: Когда Java быстрее C++ — сравнение производительности

Ну если делать так:

if (++this->counter >= this->count_max)

Toggle *toggle = new Toggle(val);
for (int i=0; i<n; i++) <
val = toggle->activate().value();
>
cout << ((val) ? "true" : "false") << endl;
delete toggle;

вместо того чтобы разместить toggle на стеке, то конечно C++ окажется медленнее. Вообще во всём этом "сравнении производительности" чувствуется явно предвзятое отношение к C++ и код на последнем подгоняется под код на джаве.

Re: Re: Когда Java быстрее C++ — сравнение производительности

> вместо того чтобы разместить toggle на стеке, то конечно C++ окажется медленнее.

Как насчет того, что в Java объекты всегда создаются именно способом "Toggle toggle = new Toggle()" ? Вроде ж нет априорного преимущества перед C++?

Re: Re: Когда Java быстрее C++ — сравнение производительности

> око вот вопрос. а кто же писал оракловый инсталятор? И чего же он так тормозит? Может лохи писали? (хотя еще не проверял как работают проги под novm java, но думаю чудес не предвидится)

Оракл гордится своими старыми jdk. Замечательный пример — jdk 1.1.8.113, стоявший у нас на работе =)))

Re: Re: Re: Когда Java быстрее C++ — сравнение производительности

>>С++ вызывает сборщик мусора для обьекта сразу, как тот перстал
>>существовать.
>Похоже я от жизни отстал. В какой из реализаций C++ появился garbage collector?

Вот честно, не знаю. Завершение жизни обьекта в JAVA устроено иначе. Цитировать книжки Java не хочеться, а в моей голове без практики ничего не задерживаеться ;-).
Могу приврать, но в Java можно как-то оживить умерший обьект, до которого не дошли руки сборщика мусора. Так что есть некоторый маневр и в этом.

А какие РЕАЛЬНЫЕ идеи есть по поводу этого теста ? Байт код не может выполняться быстрее чем машкод.
Эффективность сборки мусора, единственное, что пришло в голову.

Re: Когда Java быстрее C++ — сравнение производительности

Не забывайте ставить ссылки на первоисточник текста новости .

Re: Re: Re: Re: Когда Java быстрее C++ — сравнение производительности

2 eda:
> а в моей голове без практики ничего не задерживаеться ;-).
Угу. Все, кому надо уже поняли :-).

Re: Re: Re: Когда Java быстрее C++ — сравнение производительности

> Мусорщик — есть примочка ВМов.
В корне не верно :-). Но в C++ его-таки нативного нет и быть не может ;-).

Re: Re: Re: Когда Java быстрее C++ — сравнение производительности

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

Re: Re: Re: Re: Когда Java быстрее C++ — сравнение производительности

>А какие РЕАЛЬНЫЕ идеи есть по поводу этого теста ? Байт код не может >выполняться быстрее чем машкод. >Эффективность сборки мусора, единственное, что пришло в голову.

Повторить! Что-он попутал. гадом буду!

Re: Re: Когда Java быстрее C++ — сравнение производительности

> for ( int i = 0 ; i < 65535; i ++);

я долго думал, почему именно "65535" ?? это ведь 2^16-1, а int, наскоко мне известно (даже более того — я в этом уверен) — 4-х байтовый. (по крайней мере в нормальных системах — aka linux))

Re: Re: Re: Re: Когда Java быстрее C++ — сравнение производительности

> Вот честно, не знаю. Завершение жизни обьекта в JAVA устроено иначе.

> Эффективность сборки мусора, единственное, что пришло в голову.

Способность к аналитическому мышлению — очень хорошее качество, но в данном случае оно вас несколько подвело: в C++ нет "легализованного" сборщика мусора. Оговорки: под сборкой мусора мы понимаем автоматическое (без участия человека) освобождение неиспользуемой памяти в куче; существующим для C++ "third-party" реализациям сборщиков мусора мы выражаем наше почтение, но не считаем их частью стандартной технологии.

> Могу приврать, но в Java можно как-то оживить умерший обьект, до которого не дошли руки сборщика мусора. Так что есть некоторый маневр и в этом.

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

Re: Re: Re: Re: Когда Java быстрее C++ — сравнение производительности

> А какие РЕАЛЬНЫЕ идеи есть по поводу этого теста ? Байт код
> не может выполняться быстрее чем машкод. Эффективность сборки
> мусора, единственное, что пришло в голову.

Вообще-то на этот вопрос должен был ответить сам автор "исследования". И то, что он такого ответа не дал ещё раз подчеркивает его "ценность".

Re: Когда Java быстрее C++ — сравнение производительности

я где-то бенчмарк компайлеров видел — там идея та же: Жаба рулит.

но даже там на графиках видно, что тригонометрия /да и не только — всё что связано с фпу/ нуууу оооочень тормозииит.

Re: Re: Re: Когда Java быстрее C++ — сравнение производительности

> 4-х байтовый. (по крайней мере в нормальных системах — aka linux))

4 байта = 32 бита (i386), на 64 битной системе инт буит 8 байт занимать.

Re: Когда Java быстрее C++ — сравнение производительности

hash.cpp: for (int i=1; i<=n; i++)

ясно понятно что X[a]=.. гораздо медленей чем просто ht.put в java и X.insert в с++

Re: Re: Re: Re: Когда Java быстрее C++ — сравнение производительности

> Я о том и говорю, что в java объекты создаются исключительно в куче, тогда как в C++ их можно создавать и на стеке и это зачастую (и уж точно в данном конкретном случае) гораздо быстрее. Код на C++ подгонялся под java, а не наоборот.

Кстати, много ли вы в этих тестах увидели операторов ‘new’ (я о C++ коде) ? Я вот ткнулся наудачу в несколько файлов и ни одного не обнаружил. Если кому интересно, где исходники, ходите сюда:

Re: Re: Re: Когда Java быстрее C++ — сравнение производительности

2 nelapsi:
"О сколько нам открытий чудных. "

>а int, наскоко мне известно (даже более того — я в этом уверен) — 4-х
>байтовый.
Ты абсолютно не прав. int — размером в маш. слово. а оно может быть 1/2/3/4/5/6/7/8/9 байт. В зависимости от платформы :-). Думаешь для чего в кроссплатформенных аппликухах введены типы int16/int32 итд? 😉

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *