LINUX.ORG.RU

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


0

0

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

Источник новости: http://www.opennet.ru/opennews/art.shtml?num=3994

>>> Подробности



Проверено: Demetrio ()
Ответ на: комментарий от int19h

> Ява на линухе в БОЛЕЕ ЧЕВ ДВА РАЗА медленней, чем под Win2K, причем последняя крутится в vmware под тем же линухом! Каково, а?

даешь FreeBSD + kse :)... и никаких форков :))

anonymous
()
Ответ на: комментарий от anonymous

> а че это в яве виртуальная функция вызывается быстрее чем в С++?

Анекдот про "Открыла сумочку, достала кошелечек, закрыла сумочку" явно сочинялся бывшим плюсистом.

anonymous
()
Ответ на: комментарий от anonymous


>а че это в яве виртуальная функция вызывается быстрее чем в С++?

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



ANDI ★★
()
Ответ на: комментарий от dObryi

нормальные возможности, сеть, даже JDBC опционально и, если не в курсе, семейство ARM9 имеет поддержку байткода на уровне инструкций

dea
()

Гоняю сейчас эти тесты у себя. Правда, под виндой (WinXP Pro), и компилю VC++2003. Жаба - 1.4.2_04. Пока прогнал тест fibo, дык вот... действительно, 'java -server' показывает лучший результат, чем 'cl /G6 /Ox' (16с против 19с). Щаз попробуем код на плюсах подоптимизировать...

int19h ★★★★
()
Ответ на: комментарий от eXOR

> есть такое правило
> sizeof(int) == sizeof(void *)

Нет такого правила. Более того -- в любом букварике, хоть как-то
затрагивающем переносимость тыкают носом:

1. Вы НЕ должны полагать, что sizeof(int) == sizeof(void*)
2. Вы ВООБЩЕ не должны полагать, будто знаете чему равен sizeof(int),
если не считать гарантированного стандартом соотношения
sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)

awn
()
Ответ на: комментарий от int19h

В тесте ackermann - жаба (с вышеописанными параметрами) в два раза быстрее C++. Куда его дальше оптимизировать - я не знаю (есть предложения?).

Кстати, -server действительно заметно прибавляет производительность. Учтем.

int19h ★★★★
()
Ответ на: комментарий от int19h

А вот на умножении матриц C++ рвет жабу в клочья (8с против 21с). Похоже, что она просто лучше делает inlining, и потому обгоняет C++ на рекурсивных алгоритмах. А вот если закодить в лоб, циклом, то тут C++ явно шустрее.

Теперь возникает интересный вопрос: чего в среднестатистической гуевой приблуде больше - циклов или вызовов методов? Имхо, последнего...

int19h ★★★★
()
Ответ на: комментарий от anonymous

Я говорю о том, что в данный момент наблюдаю собственными глазами на своей машине. Можешь сам попробовать =)

int19h ★★★★
()
Ответ на: комментарий от anonymous

> А что скажет по этому поводу господин Луговский?

Что LISP всех уделает. Ну или OCAML.

BarD
()
Ответ на: комментарий от anonymous

а он c++ никогда и не любил. java, впрочем, тоже

anonymous
()

Ещё бы она память по-человечески использовала, вообще C++ на помойку можно было бы выкидывать.

anonymous
()
Ответ на: комментарий от dea

> нормалные возможности

Дядя семейство АРМ9 ставится на СМАРТФОНЫ! У которых мощей и мозгов некисло. И нативных приложений - попой ешь. А ява на простом телефоне (у которого мозгов свободных 2 метра) это 3-4 мидлета а ля задави всех лягушек, и е-майл клиент, который при каждом включении/отключении телефона конфигурять заново.

anonymous
()
Ответ на: комментарий от anonymous

> Ещё бы она память по-человечески использовала

Вы забыли один из главных лозунгов Java-программеров: "Memory Is Cheap!" ;)

int19h ★★★★
()
Ответ на: комментарий от dea

> нормалные возможности

Дядя семейство АРМ9 ставится на СМАРТФОНЫ! У которых мощей и мозгов некисло. И нативных приложений - попой ешь. А ява на простом телефоне (у которого мозгов свободных 2 метра) это 3-4 мидлета а ля задави всех лягушек, и е-майл клиент, который при каждом включении/отключении телефона конфигурять заново.

anonymous
()

Saying that Java is nice because it works on all OS's is like saying that anal sex is nice because it works on all genders.

а так - жаба рулитнепадецки :)))

HellAngel ★★
()
Ответ на: комментарий от awn

>Нет такого правила. Более того -- в любом букварике, хоть как-то
>затрагивающем переносимость тыкают носом:
Гм ;-) SGI думают по другому... но вполне возможно... За ссылочку на бувкарик буду безмерно благодарен...

eXOR ★★★★★
()
Ответ на: комментарий от int19h

>Вы забыли один из главных лозунгов Java-программеров: "Memory Is
>Cheap!" ;)
Но 64 бита только появляются в секторе middle/low.. ;-)...

eXOR ★★★★★
()
Ответ на: комментарий от eXOR

> За ссылочку на бувкарик буду безмерно благодарен

ISO+IEC+9399-1999 (aka ISO C99)

URL не дам, ибо нет его в бесплатном доступе. Но могу кинуть в pdf'ке желающим на email =)

int19h ★★★★
()
Ответ на: комментарий от eXOR

> Но 64 бита только появляются в секторе middle/low.. ;-)...

Прааавильно... и чем больше жабы - тем быстрее они там появятся! Лень - двигатель прогресса! =)

int19h ★★★★
()
Ответ на: комментарий от int19h

Весит сколько? Давай почитаю exor[aaaa]]]exor.com.ru

eXOR ★★★★★
()
Ответ на: комментарий от int19h

> Теперь возникает интересный вопрос: чего в среднестатистической гуевой приблуде больше - циклов или вызовов методов?

А гуй-негуй, машинное время то тратиться в основном на операции пользователя, ну а по затратам времени конечно в циклах больше тратится. Количественно правда вероятно методов больше, только какое это имеет значение?

anonymous
()
Ответ на: комментарий от eXOR

> Write once... debug everywhere

В случае EJB, это звучит как особо утонченное издевательство ;)

int19h ★★★★
()
Ответ на: комментарий от anonymous

> ну а по затратам времени конечно в циклах больше тратится.

Вопрос только, где эти циклы выполняются - в программе (java-код), или в системе (нативный код)?

int19h ★★★★
()
Ответ на: комментарий от int19h

> Вот что бывает, детишки, когда софт не поддерживает уникод =)

Не-а это когда такая-то хрень обнаруживается с 4-х байтовым интом... и люди кидаются на стаааарые 486 прверять скока же время их нае.... Ж) Оказалось долго.... там я по поводу того что лонг то 4-х буйтный :P.

Увидел я это и окуел какая мешанина в типах.

Кстати там про Армы9 тоже мое, подписатся забыл.

dObryi
()
Ответ на: комментарий от dObryi

> там я по поводу того что лонг то 4-х буйтный

Это они дабы backwards compatibility с 64-битным кодом не ломать.

Кстати, а вот это у меня глюки, или правда майкрософт учудил и оставил на Win64 sizeof(long)==4, при том, что sizeof(int)==8 ?

int19h ★★★★
()
Ответ на: комментарий от ANDI

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

Не, есть ещё такая фишка - Страуструп об этом писал, кеширование во время исполнения указателя на виртуальную функцию - т.е. первый раз её нашли, потом берется из таблицы с кешами для класса...

Spectr ★★★
()
Ответ на: комментарий от int19h

> Кстати, а вот это у меня глюки, или правда майкрософт учудил и оставил на Win64 sizeof(long)==4, при том, что > sizeof(int)==8 ?

:O .... Мдаа кажется на чтение абстрактных мурзилок времени надо уделять больше, иначе так вот незаметно и байт станет 9 битным :?

А мужики то не знают (С) Пузатый мужик.

dObryi
()
Ответ на: комментарий от dObryi

А что такого страшного и неправильного в девятибитном байте? Это ж не октет в конце концов.

anonymous
()
Ответ на: комментарий от anonymous

> существует такое правило: sizeof(short int)=2, sizeof(long int)=4, sizeof(int) платформозависимое. может быть как 2 так и 4 байта

Угу, sizeof(char) == 1, а для int вообще ничего не говорится - хоть 8 байт. Только интересно, зачем из c++ long long убрали (8 байт), и как теперь называть его будут??? :) Или есть тип для чисел в 8-мь байтов?

Spectr ★★★
()

Забавно. Интересно почему такая буря в стакане воды? То, что код типа 2+3 или for (всякая херня) запущенный в java server vm обгоняет код, написанный на C, скомпиленный gcc c *** -O2 *** ? Почему тот факт, что код собранный Intel C++ с глобальной оптимизацией и профайлингом обгоняет код собранный gcc -O2 не удивляет никого? jit в java server vm проводит очень агрессивную оптимизацию кода. В частности АГРЕССИВНЫЙ inline-ниг и loop unrolling. Чтобы это делал gcc нужно ставить -O3 как минимум! А вы случем не забыли, что:

1) Java GC это stop world GC.

2) Чем больше объем выделенной памяти, тем больше работы для GC.

3) Java использует copyng (young generation) + mark & compact (old generation) GC.

4) Из 3 вытекает, что все "ссылки" на объекты в java есть на самом деле handle ( как минимум указатель на указаткль на объект )

5) Из 3 вытекает, что на системах, с агрессивным кэшированием фс ( Linux ) old generation - реальный кандидат для пинг (swap in)-понга (swap out).

Я мог бы привести еще перечислять, но я полагаю, что этого достаточно для того, чтобы убедится в том, что НУ НЕ МОЖЕТ РЕАЛЬНОЕ ПРИЛОЖЕНИЕ НАПИСАННОЕ НА Java РАБОТАТЬ БЫСТРЕЕ ЧЕМ ОНО НА С/С++, что и показывает практика. К стати товарисч, которые недоумевает - как можно писать сервера приложений на C++ ответственно заявляю - можно сынок - только работа для людей с мозгами и поверь - ничуть не сложнее чем ляпать j2ee компоненты.

Captain.

P.S.

Товарисч, который утверждает, что можно выделять память быстрее чем C++ делает на стеке ( ala "add -sizeof(object), %esp" ) ОЧЕНЬ ПРОШУ ПОДЕЛИТСЯ. Для самообразования так сказать.

Детский сад твою мать.

anonymous
()
Ответ на: комментарий от dObryi

Извиняюсь. sizeof(int) там тоже равно четырем. Каюсь и посыпаю голову пеплом.

... а хорошо все-таки, что в той же яве таких вопросов не возникает =)

int19h ★★★★
()
Ответ на: комментарий от anonymous

2Captain: Умный - Но стремный !

Зачем бури в стакане - вопрос скорее из области психологии. Кстати, сечас начнутся не менее умные опровержения... :))))))

ЗЫ: Ты че злой такой ?

dObryi
()
Ответ на: комментарий от Spectr

> Только интересно, зачем из c++ long long убрали (8 байт)

А его там и не было никогда. Он и в C появился только в 99-м, то есть уже после выхода спецификации на C++.

Но вроде бы в следующей версии обещали включить.

int19h ★★★★
()
Ответ на: комментарий от int19h

(Пряча в стол валидол) Ну и ладухи! А голову пеплом посыпать не нуно - все ошибаются. А по поводу невозникновения таких вопросов в яве..., а как тогда там осуществлять скажем разбор структурированных бинарей, когда в спецификациях мешанина вроде .. "по такому смещению MSB long по такому int 3 октета а здесь int..." и нифига не сказано что они подразумевают под этим самым int ?

dObryi
()
Ответ на: комментарий от anonymous

> Ну наконец-то.... Респкет!

Респект за что ? Тут дядя все вроде ребята с головой и понимают, что в данном случае произошел простой обмен призводительности на ресурсы. И НИЧЕГО пояснительного в его утверждении кроме урывочных воспоминаний и 3.14здато развитого самолюбия я чегой-то не заметил.

dObryi
()

Цитата из objinst.cpp: for (int i=0; i<n; i++) { Toggle *toggle = new Toggle(true); delete toggle; } если кто в здравом уме и будет такое делать, то скорей всего переопределит операторы new и delete, что бы не резервировать память в куче на каждой итерации... Статья показывает лишь то, что плохой C++ код медленнее хорошего Java-кода.

anonymous
()
Ответ на: комментарий от anonymous

>http://www.cs.princeton.edu/~appel/papers/45.ps

Ничего нового. Статья действительно называется "Garbage collection can be faster than stack allocation", однако в статье рассматривается давно известный COPYING GC. Вполне согласен, что аллокация в этом случае НЕ МЕДЛЕННЕЕ чем аллокация на стеке. К стати как авторы НЕ УТВЕРЖДАЮТ, что быстрее: "Thus, allocating a cell from the heap is IDENTICAL in cost to pushing a cell onto the stack". Ну а название статьи - просто PR. Посмотрите хотябы как они туманят, когда речь заходит о сборке мусора.

Captain.

anonymous
()
Ответ на: комментарий от int19h

и что же именно ты наблюдаешь? среднестатистическую гуевую приблуду? :-)

Я говорю о том, что циклы тут не причина, в том же скрине, если уж тебе лень глянуть Жаба с треском проиграла на перемножении матриц.

anonymous
()
Ответ на: комментарий от anonymous

> Товарисч, который утверждает.....

Я конечно не товарисч который утверждает, и яву я не рублю...

Но на вскидку если оттулкнутся от чисто моей больной фантазии что ты понимаешь под "выделением памяти" в сях и виртуальной машине ???

В сях конечно память могет выделятся быстро, но...

В виртуальной машине некоторый объем памяти ФИЗИЧЕСКИ уже того... выделен при инициализации приложения внутри ВМ (я бы так и сделал), и то что называется выделит память в вм - это всего лишь дать разрешение байт-коду писать в такие-то адреса - а это БЫСТРЕЕ. Не факт, что память будет ВСЕГДА выделятся быстрее, но на разовых потугах МОЖЕТ быть быстрее.

dObryi
()
Ответ на: комментарий от dObryi

Смотрим http://www.kano.net/javabench/src/java/matrix.java:

public static int[][] mkmatrix (int rows, int cols) { int count = 1; int m[][] = new int[rows][cols]; for (int i=0; i<rows; i++) { for (int j=0; j<cols; j++) { m[i][j] = count++; } } return(m); }

Смотрим http://www.kano.net/javabench/src/cpp/matrix.cpp:

int **mkmatrix(int rows, int cols) { int i, j, count = 1; int **m = (int **) malloc(rows * sizeof(int *)); for (i=0; i<rows; i++) { m[i] = (int *) malloc(cols * sizeof(int)); for (j=0; j<cols; j++) { m[i][j] = count++; } } return(m); }

А надо бы (подстрочник с жабакода):

int **mkmatrix(int rows, int cols) { int i, j, count = 1; int **m = (int **) malloc(rows * cols * sizeof(int)); for (i=0; i<rows; i++) { for (j=0; j<cols; j++) { m[i][j] = count++; } } return(m); }

Почему для java массива память выделяется за один раз, а для C++ - один раз плюс столько раз, сколько в массиве рядов?

Соответственно

void freematrix(int rows, int **m) { while (--rows > -1) { free(m[rows]); } free(m); }

превращается в

void freematrix(int **m) { free(m); }

или еще лучше - в

inline void freematrix(int **m) { free(m); }

Дальше пока не стал смотреть, но, похоже, тест - фуфло...

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.