Я не верю своим глазам! Java быстрее, чем C++???

 
+
-
edit
 

Balancer

администратор
★★★★★
code java
  1. import java.lang.*;
  2. class fib
  3. {
  4.     static int fibn(int n)
  5.     {
  6.         return n<2 ? 1 : fibn(n-1) + fibn(n-2);
  7.     }
  8.  
  9.     public static void main(String[] args)
  10.     {
  11.         System.out.println(fibn(42));
  12.     }
  13. }


code cpp
  1. #include <stdio.h>
  2.  
  3. int fib(int n)
  4. {
  5.     return n<2 ? 1 : fib(n-1)+fib(n-2);
  6. }
  7.  
  8.  
  9. void main(void)
  10. {
  11.     int f42=fib(42);
  12.     printf("%d",f42);
  13. }


Компиляция первого - javac fib.java (JDK 1.5)
Второго - cl /Ox /O2 /Fa /FAsc /G6 /Gr fib.cpp (VC7)

Время работы первого - 4.6 сек.
Время работы второго - 7.0 сек.
(предыдущий лидер, O'Caml - 6.5сек)

Как такое может быть?? JIT в Java 1.5 стал настолько хорош??
 
+
-
edit
 

Balancer

администратор
★★★★★
Под Linux на Авиабазе:
code text
  1.  # time java fib
  2. 433494437
  3. real    0m11.266s
  4. user    0m11.204s
  5. sys     0m0.023s
  6.  
  7.  # time ./a.out
  8. 433494437
  9. real    0m9.599s
  10. user    0m9.595s
  11. sys     0m0.001s


Тут Java по-прежнему уступает немного нативному коду.

Выходит, удалось такой качественный оптимизатор под windows сделать? или?
 
BG [Реконструктор] #25.03.2005 00:26
+
-
edit
 
Что, опять флейм разводиш? :) В общем, некоторые языки чем-то превозходят немножко Ц++. И в остальном СИЛЬНО ему уступают. Вот поэтому Ц++ не имеет альтернативы.
 
RU Centuriones #25.03.2005 02:18  @[Реконструктор]#25.03.2005 00:26
+
-
edit
 

Centuriones

опытный

Реконструктор> Что, опять флейм разводиш? :) В общем, некоторые языки чем-то превозходят немножко Ц++. И в остальном СИЛЬНО ему уступают. Вот поэтому Ц++ не имеет альтернативы. [»]

Это ты про ассемблер ;)

Раньше были времена,
А теперь мгновения.
Раньше поднимался дух,
А теперь давление.
 
+
-
edit
 

Balancer

администратор
★★★★★
Реконструктор>И в остальном СИЛЬНО ему уступают.

В чём?? :D Хоть в чём-то, кроме возможности генерации низкоуровневого кода (что важно, разве что, принаписании драйверов :D) C++ превосходит Java? :) Сборка мусора? Замыкания? Runtime-информация? Всевозможные проверки? Компактность кода? Отлавливание кучи ошибок на этапе трансляции? Гибкий и мощный синтаксис?

До последнего, хоть небольшой, но в скорости выигрышь был. И что теперь? Сабж! :D

...

Кстати, в области серьёзного программирования C++ так и не прижился. Все Linux'ы, BSD и т.п., оболочки к ним, браузеры, почтовики, утилиты - это всё чистый Си. Ну а OpenOffice - это уже Java :)
 
RU Centuriones #25.03.2005 18:45  @Balancer#25.03.2005 13:38
+
-
edit
 

Centuriones

опытный

Balancer> Кстати, в области серьёзного программирования C++ так и не прижился. Все Linux'ы, BSD и т.п., оболочки к ним, браузеры, почтовики, утилиты - это всё чистый Си. Ну а OpenOffice - это уже Java :) [»]

А серьезны расчетные проекты (ANSYS и подобные) — как правило fortran 90/95. :)

Кстати, про чашечку "кофе". У меня сейчас стоит Java 1.4.2_01. Естественно, жизнь заставляет переходить на нечто новое. Думал перейти на версию 1.4.2_06, но, по-видимому, лучше сразу на 1.5? Есть смысл, или все-же пока подождать отлова "жучков" и "исправлений безопасности", что характерно для новых версий? Или эта версия (1.5) уже хорошо "опрыскана дихлофосом" и в окнах не "битые стекла", а "стальные ставни"? :)
Раньше были времена,
А теперь мгновения.
Раньше поднимался дух,
А теперь давление.
 
Это сообщение редактировалось 25.03.2005 в 18:56
+
-
edit
 

Balancer

администратор
★★★★★
Не знаю, пока не слышал про баги в 1.5
Тем более, версия не новая, ей уже с год, наверное :)

Обратная совместимость, как обычно, на высоте, а вот новых фич немало полезных. Сейчас многие начали программировать под 1.5 only.
 
+
-
edit
 

Balancer

администратор
★★★★★
Кстати, похоже, всё ж, частная особенность. Какая-то оптимизация, которую отловил JIT. Вычисление функции Аккермана на Java, как и раньше, процентов на 20 медленнее, чем на C++.
 
RU Alex Privalov #25.03.2005 21:07
+
-
edit
 

Alex Privalov

новичок
Результаты тестирования на Celeron 1200/256МБ ОЗУ/WinXP совсем другие:
VC++ 6 (компиляция с указанными выше опциями) — 9.4с
JDK 1.5 — 10.4с
Это минимальное время (с учетом загрузки) из десяти последовательных запусков.

Вообще, imho, рекурсивные Фибоначчи — не показательный пример.
 
+
-
edit
 

digger

аксакал

Именнo, чтo не пoзaкaтельный : этo пример тoлькo нa скoрoсть вызoвa и рaзмoтку рекурсии oптимизaтoрoм. Вoт пoлезный


Performance


xslt performance

// www.dpawson.co.uk
 
 
+
-
edit
 
Реконструктор>>И в остальном СИЛЬНО ему уступают.
Balancer> В чём?? :D Хоть в чём-то, кроме возможности генерации низкоуровневого кода (что важно, разве что, принаписании драйверов :D) C++ превосходит Java? :) Сборка мусора? Замыкания? Runtime-информация? Всевозможные проверки? Компактность кода? Отлавливание кучи ошибок на этапе трансляции? Гибкий и мощный синтаксис?
Balancer> До последнего, хоть небольшой, но в скорости выигрышь был. И что теперь? Сабж! :D

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

Balancer> Кстати, в области серьёзного программирования C++ так и не прижился. Все Linux'ы, BSD и т.п., оболочки к ним, браузеры, почтовики, утилиты - это всё чистый Си. Ну а OpenOffice - это уже Java :) [»]

Вот это уже что-то новое. :) И, конечно, абсолютно неправильное. Иди в любой софтверный магазин, и выбери любых, скажем 10 продуктов. Любых - КАД системы, софт для обработки видео, рестерных и векторных график, системы 3Д анимации, игры, ОС, офис пакеты, софт для обработки аудио и т.д. Потом попытайся выяснить историю выбранных продуктов. И возвращайся сюда с докладом.
Еще раз повторяю - твои тесты ничего не значат. Попробуй придумать некоторые более практические задачи, напр. линейная интерполяция, обработка больших массивов информации и т.д. Тогда я уверен, что будеш кланятся C++ как богу.
 

Vale

Сальсолёт

Кстати, Олег Медокс, по слухам, переписывает движок "Ил-2" с Java на С++ ;)
"Не следуй за большинством на зло, и не решай тяжбы, отступая по большинству от правды" (Исх. 23:2)  
Движок Ил-2 написан на жабе!?!?!? Ужас какой. Прям кошмар ночной. А я вот думал, почему это он такой тормозной и памяти жрет немеряное количество?
 
+
-
edit
 

Balancer

администратор
★★★★★
Guest> Движок Ил-2 написан на жабе!?!?!? Ужас какой. Прям кошмар ночной. А я вот думал, почему это он такой тормозной и памяти жрет немеряное количество? [»]

Написанный на Си движок Lock-On'а тормознее при тех же параметрах :D

Ссылочку на сравнения Quake-движков на Си и Java я уже давал - Быстродействие языков. Java vs Си. Quake 2 :)
 

SEA

втянувшийся

Здесь не С медленнее, а компилятор VC медленнее, что не удивительного.
Майкрософт компилятор никогда не славился оптимизацией кода.
Что и можно наблюдать в ассемблерном листинге.

Кстати, включение опции /Gr только ухудшило время. Исправить ситуацию удалось, используя С-стиль передачи параметров в функцию /Gd, а функцию fib(int n) объявить как:
int __fastcall fib(int n)

Но код все равно не идеальный. Хорошо сгенерированный код и выполнялся бы не медленнее чем Java. Или так же.
 
RU Alex Privalov #26.03.2005 17:49
+
-
edit
 

Alex Privalov

новичок
Я пробовал переписать рекурсивное БПФ "на месте" с С++ на Java (все тот же JDK 1.5). Итог - скорость уменьшилась в 15 раз, пожираемый объем памяти увеличился на порядок. К тому же, отсутствие перегрузки операторов в данном случае несколько напрягает. Если избавится от собственного класса для комплексных чисел и всего с ним связанного, отставание резко сокращается. Но это уже мазохизм — в таком исходнике просто невозможно разобраться.

Из "реального" софта почему-то сразу вспоминается NetBeans. Для комфортной работы с этим чудом надо минимум 512МБ ОЗУ — всего лишь IDE, пусть даже с кучей наворотов. Цифра просто немыслимая для нормального С++ программиста.

После этого тесты, где Java близка по быстродействию к C++, как-то не воспринимаются.
 
+
-
edit
 

Balancer

администратор
★★★★★
SEA> Майкрософт компилятор никогда не славился оптимизацией кода.

Хех. "А мужики-то и не знают". Хотя, конечно, может, ICC и лучше, не щупал. Но вряд ли кардинально. А вот Watcom и GCC проигрывают MSVC уже несколько лет.
 
RU Balancer #26.03.2005 19:14  @Alex Privalov#26.03.2005 17:49
+
-
edit
 

Balancer

администратор
★★★★★
A.P.> Из "реального" софта почему-то сразу вспоминается NetBeans.

А eclipse?

A.P.> После этого тесты, где Java близка по быстродействию к C++, как-то не воспринимаются. [»]

Даже когда это не в одну функцию тест, а движок Quake? :)

На любом языке можно написать безумно тормозную вещь в рамках одного и того же алгоритма :)

...

Java, всё же, не C++ и в лоб переносить на неё - это неоптимально. Почти всегда нужно делать серьёзный пересмотр кода в сторону использования новых возможностей.
 
+
-
edit
 

Balancer

администратор
★★★★★
SEA> Кстати, включение опции /Gr только ухудшило время.

Без неё - медленнее на ~15%

> Исправить ситуацию удалось, используя С-стиль передачи параметров в функцию /Gd, а функцию fib(int n) объявить как:
SEA> int __fastcall fib(int n)

Скорость выходит такая же. И не мудрено, т.к.:

code 6502acme
  1. ; 4    : {
  2.  
  3.   00000 57               push    edi
  4.   00001 8b f9            mov     edi, ecx
  5.  
  6. ; 5    :        return n<2 ? 1 : fib(n-1)+fib(n-2);
  7.  
  8.   00003 83 ff 02         cmp     edi, 2
  9.   00006 7d 07            jge     SHORT $L612
  10.   00008 b8 01 00 00 00   mov     eax, 1
  11.   0000d 5f               pop     edi
  12.  
  13. ; 6    : }
  14.  
  15.   0000e c3               ret     0
  16. $L612:
  17.   0000f 56               push    esi
  18.  
  19. ; 5    :        return n<2 ? 1 : fib(n-1)+fib(n-2);
  20.  
  21.   00010 8d 4f fe         lea     ecx, DWORD PTR [edi-2]
  22.   00013 e8 00 00 00 00   call    ?fib@@YIHH@Z           ; fib
  23.   00018 8d 4f ff         lea     ecx, DWORD PTR [edi-1]
  24.   0001b 8b f0            mov     esi, eax
  25.   0001d e8 00 00 00 00   call    ?fib@@YIHH@Z           ; fib
  26.   00022 03 f0            add     esi, eax
  27.   00024 8b c6            mov     eax, esi
  28.   00026 5e               pop     esi
  29.   00027 5f               pop     edi
  30.  
  31. ; 6    : }


А вот что с /Gr:

code 6502acme
  1. ; 4    : {
  2.  
  3.   00000 57               push    edi
  4.   00001 8b f9            mov     edi, ecx
  5.  
  6. ; 5    :        return n<2 ? 1 : fib(n-1)+fib(n-2);
  7.  
  8.   00003 83 ff 02         cmp     edi, 2
  9.   00006 7d 07            jge     SHORT $L613
  10.   00008 b8 01 00 00 00   mov     eax, 1
  11.   0000d 5f               pop     edi
  12.  
  13. ; 6    : }
  14.  
  15.   0000e c3               ret     0
  16. $L613:
  17.   0000f 56               push    esi
  18.  
  19. ; 5    :        return n<2 ? 1 : fib(n-1)+fib(n-2);
  20.  
  21.   00010 8d 4f fe         lea     ecx, DWORD PTR [edi-2]
  22.   00013 e8 00 00 00 00   call    ?fib@@YIHH@Z           ; fib
  23.   00018 8d 4f ff         lea     ecx, DWORD PTR [edi-1]
  24.   0001b 8b f0            mov     esi, eax
  25.   0001d e8 00 00 00 00   call    ?fib@@YIHH@Z           ; fib
  26.   00022 03 f0            add     esi, eax
  27.   00024 8b c6            mov     eax, esi
  28.   00026 5e               pop     esi
  29.   00027 5f               pop     edi
  30.  
  31. ; 6    : }


Как говорится, найдите 10 отличий.

Может, у тебя MSVC какой-нибудь 3-й версии? :D
 
RU Alex Privalov #26.03.2005 21:12
+
-
edit
 

Alex Privalov

новичок
Balancer>А eclipse?

А с Eclipse почти не работал, поэтому ничего не скажу. В любом случае, NetBeans ведь не из вредности таким ресурсоемким написали? И вряд ли из-за того, что программисты криворукие.

Balancer>Даже когда это не в одну функцию тест, а движок Quake?

Это опять же не совсем корректный метод сравнения "быстродействия языков". Хотелось бы посмотреть, как будет работать Quake на Java с софверным рендерингом на той же Java. Или не Quake, а хотя бы алгоритм обратной трассировки лучей (его, например, AutoCAD использует).

Balancer>Java, всё же, не C++ и в лоб переносить на неё - это неоптимально. Почти всегда нужно делать серьёзный пересмотр кода в сторону использования новых возможностей.

Хорошо, допустим есть такой код на C++:
code text
  1. #include <stdio.h>
  2.  
  3. class Complex
  4. {
  5. public:
  6.         Complex(double re, double im): re(re), im(im) {}
  7.  
  8.         double re;
  9.         double im;
  10. };
  11.  
  12. inline Complex operator+(const Complex& a, const Complex& b) {
  13.         return Complex(a.re + b.re, a.im + b.im); }
  14.  
  15. int main(int argc, char* arv[])
  16. {
  17.         Complex z(0, 0);
  18.         for (int i = 0; i < (1 << 26); ++i) z = z + Complex(1, 0);
  19.         printf("%f\n", z.re);
  20.         return 0;
  21. }


Как его переписать на Java с сохранением наглядности и без катастрофических последствий для быстродействия? Условия: Complex(1, 0) создавать внутри цикла, а оператор сложения заменять только эквивалентом (а не аналогом +=).
 
Это сообщение редактировалось 26.03.2005 в 21:19
+
-
edit
 

Balancer

администратор
★★★★★
A.P.> Хорошо, допустим есть такой код на C++:

В лоб, без всякой оптимизации (на таком простом примере оптимизировать нечего :) )
code java
  1. public class Complex
  2. {
  3.     public double _re;
  4.     public double _im;
  5.  
  6.     Complex(double re, double im)
  7.     {
  8.         _re = re;
  9.         _im = im;
  10.     }
  11.  
  12.         public Complex add(Complex a)
  13.         {
  14.         return new Complex(a._re + _re, a._im + _im);
  15.     }
  16.  
  17.     public static void main(String[] args)
  18.     {
  19.             Complex z = new Complex(0, 0);
  20.         for (int i = 0; i < (1 << 26); ++i)
  21.                 z = z.add(new Complex(1, 0));
  22.  
  23.         System.out.println(z._re);
  24.         }
  25. }


Пригрышь двухкратный. 6.5сек против 3.0.

Много, конечно, но не в 15 же раз :)

При чём хорошо видно, откуда оно лезет - при такой реализации происходят лишние создания классов.

Уже вариант
code java
  1. public class Complex
  2. {
  3.     public double _re;
  4.     public double _im;
  5.  
  6.     Complex(double re, double im)
  7.     {
  8.         _re = re;
  9.         _im = im;
  10.     }
  11.  
  12.         public void add(Complex a)
  13.         {
  14.         _re += a._re;
  15.         _im += a._im;
  16.     }
  17.  
  18.     public static void main(String[] args)
  19.     {
  20.             Complex z = new Complex(0, 0);
  21.         for (int i = 0; i < (1 << 26); ++i)
  22.                 z.add(new Complex(1, 0));
  23.  
  24.         System.out.println(z._re);
  25.         }
  26. }

выполняется всего за 3.7 сек, что лишь на 23% медленнее, чем на Си++
 
RU Alex Privalov #26.03.2005 22:49
+
-
edit
 

Alex Privalov

новичок
>Пригрышь двухкратный. 6.5сек против 3.0.

У меня 23сек против 2.17сек. В чем может быть причина столь различных результатов? Проц Celeron 1200

>При чём хорошо видно, откуда оно лезет - при такой реализации происходят лишние создания классов

Это само собой, пример так и задуман.
 

SEA

втянувшийся

Balancer:
Как говорится, найдите 10 отличий.
Может, у тебя MSVC какой-нибудь 3-й версии?
 


:)
Да нет, VC Net , который с со студио 7.

Просто я не использовал мэекфайл, а задавал параметры компиляции в project properties, и пропустил опцию /Gr :)
Ну и поглядев на ассемблер, включил это принудительно с __fastcall.


Кстати, опции /Ox и /O2 вместе задать невозможно. Или одна или другая.
 
+
-
edit
 

Balancer

администратор
★★★★★
A.P.> У меня 23сек против 2.17сек. В чем может быть причина столь различных результатов? Проц Celeron 1200

Понятия не имею :-/ М.б. JavaVM стала использовать SSE для плавучки? Хотя как раз в этом случае выигрышь не должен быть замтным на этом.

Кстати, как я уже упоминал, на Linux/Xeon-1800 проигрышь Java в Фибоначчи был примерно процентов 20, ЕМНИП. Надо будет этот тест тоже там прогнать.
 

Balancer

администратор
★★★★★
SEA> Просто я не использовал мэекфайл, а задавал параметры компиляции в project properties, и пропустил опцию /Gr :)

Могу только сказать, что одиночные *.cpp у меня компилятся и запускаются BAT-файлом, вся компиляция в котором идёт с командной строки. makefile делать для одиночного файла - я до такого ещё не дожил, а запускать GUI ради этого - надеюсь, что и не доживу никогда :D

SEA> Кстати, опции /Ox и /O2 вместе задать невозможно. Или одна или другая. [»]

Если память не изменяет (года два в ключи не смотрел - как сделал BAT'ник, так им и пользуюсь), вторая "групповая" опция не отменяет первую, а только меняет в ней "несовместимые" с ней подопции.
 

в начало страницы | новое
 
Поиск
Настройки
Твиттер сайта
Статистика
Рейтинг@Mail.ru