LINUX.ORG.RU

Java тормозит? А вот и нет! :)


0

3

Попробовал сравнить программы, вычисляющие число пи, написанные на C и Java. Использовал Ряд Лейбница. Вот что получилось:

Java (JRE 1.6): 18 с

C (gcc 4.4.3 с -O2): 24 c

public class Main {
    public static void main(String[] args) {
        double pi = 0.0;
        int z = 1;

        for (int i = 1; i <= 2000000000; i++)
        {
            pi += (1.0 / ((i*2)-1)) * z;
            z *= -1;
        }

        System.out.println(pi*4);
    }
}
#include <stdio.h>

int main(void)
{
    double pi = 0.0;
    int z = 1, i;

    for (i = 1; i <= 2000000000; i++)
    {
        pi += (1.0 / ((i*2)-1)) * z;
        z *= -1;
    }

    printf("%.15f\n", pi*4);
}

PS. Я C программист, к яве отношения не имею :)

Ответ на: комментарий от x3al

И вариант bga_

@madoka~>time ./a.out
3.141592653082270
./a.out 10.64s user 0.00s system 99% cpu 10.643 total

x3al ★★★★★
()

Хех =)

Это не пример для сравнения... ИМХО. Скачай игру minecraft и запусти на слабой машине, а потом скачай клон на С++ и он будет работать шустрее. С++ программист-любитель, к джаве тоже отношения не имею, НО мне не трудно сравнивать одинаковые программы на двух языках. Джава тормозит? А вот и нет, она подтормаживает =)

Ещё посмотри в инете диаграмки. С(С++) выигрывает не во всех тестах, но во многих. Вот так то.

Кстати мой тест:

L: C++ T: 21 сек C: g++ 2005 года

NaViKotE
()

У меня жава занимает оба ядра. Если сделать сишный вариант многопоточным, то все встает на свои места.

 #include <stdio.h>
 
 int main(void)
 {
     double pi = 0.0;
     
 #pragma omp parallel for reduction(+:pi)
     for (int i = 1; i <= 2000000000; i++)
     {   
         pi += (i & 1) == 1 ? (1.0 / ((i*2)-1)) : -(1.0 / ((i*2)-1));
     }
     
     printf("%.15f\n", pi*4);
 }
gcc -std=c99 -fopenmp main2.c -O3 -o main
time ./main 
3.141592658505666

real	0m21.881s
user	0m41.483s
sys	0m0.052s

time java Main 
3.141592658505181

real	0m37.541s
user	0m42.623s
sys	0m23.337s

tim239 ★★
()

>z *= -1

Жесть какая. СиГМ? :)

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

> Ряд Лейбница неабсолютно сходящийся, его члены нельзя произвольно группировать.

можно :-)

у нас же конечные суммы

в худшем случае получим примерно в ln n раз бОльшие суммы, которые вычтутся с небольшой потерей точности

www_linux_org_ru ★★★★★
()

Рекомендую использовать разложение в ряд не arctg(x), a arcsin(x), так как он сходится быстрее намного. И считать его либо при x = 1/2 (PI/6), либо при x = 1 (PI/2).

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

Скачай игру minecraft и запусти на слабой машине, а потом скачай клон на С++ и он будет работать шустрее.

какие клоны? нет у него полнофункциональных клонов.

А minecraft, даже на слабой машине, со сторонними патчиками работает очень шустро

derlafff ★★★★★
()
Ответ на: С zsh выглядит слишком толсто. от x3al

> 2 ядра. java юзает оба.

без разрешения??? нет пути!

$ time java -server -Xbatch Main
3.141592658505181

real    0m16.458s
user    0m18.088s
sys     0m6.821s
$ time taskset -c 0 java -server -Xbatch Main
3.141592658505181

real    0m27.234s
user    0m18.531s
sys     0m8.423s
$ _

вот теперь всё честно ;)

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

> какие клоны? нет у него полнофункциональных клонов.

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

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

или можно пойти другим путём:

$ cat test.c
#include <stdio.h>

int main(void)
{
    double pi = 0.0;
    int z = 1, i;

#pragma omp parallel for
    for (i = 1; i <= 2000000000; i++)
    {
        pi += (1.0 / ((i*2)-1)) * z;
        z *= -1;
    }

    printf("%.15f\n", pi*4);
}
$ gcc -O2 -ansi -fopenmp test.c -o test_gcc
$ time test_gcc
3.141592652588050

real    0m10.773s
user    0m18.339s
sys     0m0.080s
$ _

;)

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

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

anonymous
()

На моем ноутбуке (Archlinux x64) gcc показал лучшие относительно java результаты:

$ time java Main
3.141592658505181

real    1m10.437s
user    0m49.400s
sys     0m19.559s

$ gcc -O2 pi.c -o pi
$ time ./pi
3.141592658505181

real    0m51.555s
user    0m50.373s
sys     0m0.010s
Genuine ★★★
()
Ответ на: Java тормозит? от nanoo_linux

Запусти эклипсу и убедись


А ты скакимиключами запускаешь?

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

без разрешения??? нет пути!

@madoka~/tmp/java-тормоз>time taskset -c 0 java Main 
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on
3.141592658505181
taskset -c 0 java Main  10.67s user 0.02s system 98% cpu 10.837 total

Те же 11 секунд. На C с этим сравним только вариант bga_, -O3 -ffast-math не помогает. Ничего не понимаю.

x3al ★★★★★
()

У меня скорость примерно одинаковая. Старый двухядерный Core2 Duo T7700.

$ time java Main
3.141592658505181

real	0m27.750s
user	0m32.626s
sys	0m16.685s

$ time ./main 
3.141592658507564

real	0m28.757s
user	0m28.750s
sys	0m0.000s

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

dave ★★★★★
()
Ответ на: комментарий от x3al
@madoka~/tmp/java-тормоз>cc t2.c -O3 -fopenmp -ffast-math -march=native -msse3 -mfpmath=both
@madoka~/tmp/java-тормоз>time ./a.out                                                       
3.141592652588050
./a.out  10.67s user 0.03s system 196% cpu 5.442 total

Кажется, рекорд.

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

Работает одинаково за ~11 секунд что sun-jre-bin-1.6, что icedtea6-bin.

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

-O3 -ffast-math не помогает

Помогает с -march=native.

@madoka~/tmp/java-тормоз>cc t.c -O3 -ffast-math -march=native                      
@madoka~/tmp/java-тормоз>time ./a.out                        
3.141592658505181
./a.out  10.65s user 0.00s system 99% cpu 10.653 total
В t.c — исходный вариант.

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

> Но даёт бо́льшую ошибку.

да у меня гцц вообще иногда 0.000000000500000 выдает %)

другие:

$ /opt/sunstudio12.1/bin/c89 -L/opt/sunstudio12.1/rtlibs/amd64 -xopenmp=parallel -xO5 test.c -o test_sun
$ time OMP_NUM_THREADS=2 LD_LIBRARY_PATH=/opt/sunstudio12.1/rtlibs/amd64 test_sun
3.141592652588050

real    0m9.866s
user    0m16.597s
sys     0m0.059s
$ /opt/intel/Compiler/11.1/069/bin/intel64/icc -openmp -O2 test.c -o test_icc
$ time LD_LIBRARY_PATH=/opt/intel/Compiler/11.1/069/lib/intel64 test_icc
3.141592652588050

real    0m10.017s
user    0m16.926s
sys     0m0.061s
$ _
arsi ★★★★★
()

Жава тормозит из-за того, что типичные приложения перегружены всякими гавнолибами. Т.е. тормозит не жава, а гавнолибы. Жабка вообще шустренькая.

dizza ★★★★★
()

PGO

$ gcc 2.c -o tst -O2

$ time nice -n -20 ./tst
3.141592658505181

real	0m19.976s
user	0m19.600s
sys	0m0.000s

$ time nice -n -20 ./tst
3.141592658505181

real	0m19.979s
user	0m19.610s
sys	0m0.000s

gcc 2.c -o tst -O2 -funroll-loops -ffast-math -fprofile-use=./tmp

$ time nice -n -20 ./tst
3.141592658505181

real	0m16.543s
user	0m16.200s
sys	0m0.010s

$ time nice -n -20 ./tst
3.141592658505181

real	0m16.549s
user	0m16.210s
sys	0m0.010s
Код из ОП-поста.

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

Какие либы вам не нравятся и чем их заменить? Предлагаете не юзать ничего от Apache, например сеймейство commons-*?

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

Не ну это же маленькие либы.

Предлагаю не юзать JEE. От товарища из яндекса слышал, что они там отказались от AOP. Так что Spring видимо тоже придется выкинуть, если хочешь сохранить скорость «как на Си».

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

Всегда нужно смотреть что конкретно делается. Взять бы Spring. Какой вред от простого связывания бинов и вычитывания опций конфигурации их конфигов? Естественно 100500 интерсепторов всяких не будут работать быстро. Но ведь они что-то делают, а не просто тормозят. Не нужно, не юзайте

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

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

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

Хотя вот с этим:

«Какой вред от простого связывания бинов и вычитывания опций конфигурации их конфигов?»

не так все просто. Там же over 900 proxy объектов создается. Да то же AOP взять.

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

Вообще я точно сказать не могу, давно уже на Guice переехал. Он вроде быстренький. Пока это оптимальнейшая технология в плане удобства и производительности. Но он там тоже прокси создает. Хотя вроде как технология вылизаная гуглом и работает на ура быстро.

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

Вроде нормальна штука, хотя Spring как-то очевиднее. Тыкал Guice, там концепция показалась немного странноватой. Может не дочитал чего

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

Spring замечателен своей изкаробочностью, да. А вот всякие извраты делать в guice проще - он банально проще внутри устроен. А spring как-то разъелся к 3-й версии, что мама (т.е. JEE:) ) не горюй.

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

Я бы сказал очевидности у него больше. У его IoC. <bean> практически однозначно превращается в Java код. Отличие только в слежении за зависимостями, а не в последовательном выполении, как было бы при дословном выполнении переписаного Java кода

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

Ну на таком уровне Guice и Spring практически одинаковы, вместо @Component/<bean> и @Autowired/<ref> будет bind... и @Inject. Мож действительно просто не дочитал.

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

Ну как я понял если нужно создать обьект и в нем задать например 10 свойств (пускай примитивных), то нужно писать провайдер, что есть лишней сущностью. Или как короче? Но если нужно другой обьект, то он задается как зависимость, как я понял. Это разные подходы, которые нужно мешать вместе, вместо простой декларации <bean> с унифицированой установкой свойств

Может все реально удобнее, а я еще не понял, надо поюзать чтобы понять.

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

Ну как я понял если нужно создать обьект и в нем задать например 10 свойств

Так?

public class A {		
		
}

public static class B {
	public String foo;
	public int bar;
	public A a;
}

Если да, то конфиг для жуйса будет такой:

@Override
protected void configure() {
	bind(A.class).in(Scopes.SINGLETON);
}
	
@Provides @Singleton
protected B b(A a) {
	B b = new B();
	b.foo = "str";
	b.bar = 10;
	b.a = a;
	return b;
}

Или если хочется большей единообразности в стиле спринга то вот так:

@Override
protected void configure() {}
	

@Provides @Singleton
protected A a() {
	return new A();
}
	
@Provides @Singleton
protected B b(A a) {
	B b = new B();
	b.foo = "str";
	b.bar = 10;
	b.a = a;
	return b;
}
dizza ★★★★★
()
Ответ на: комментарий от vertexua

Я было кинулся на этот java configuration, думал обратно вернутся на Spring. Но во-первых этот конфиг оказался не самодостаточен, например aop транзакции я смог сконфигурить только в xml, а во-вторых у guice все же больше гибкости за счет более богатого языка конфигурирования. Может потом они таки допилят. Но тут с другой стороны Guice становится все популярнее и популярнее, так что не понятно кто выиграет :)

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

Никто не выиграет, это разные вещи. Кому нужен только IoC, те могут юзать Guice, кому нужно чтобы фреймворк делал за разработчика все, кроме еды и интимной жизни, те возьмут Spring.

vertexua ★★★★★
()

Вторая страница подходит к концу, но тема не раскрыта - тормозит жаба или нет? Сколько что ядер использует и т.п.? Где какие оптимизации и т.п. возможны...

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

Здесь тормозить нечему.

На одном ядре java сравнима с C.
./a.out 10.64s user 0.00s system 99% cpu 10.649 total
taskset -c 0 java -Xbatch Main 10.69s user 0.01s system 99% cpu 10.712 total
На двух ядрах java не получает серьзёзного ускорения.
java -Xbatch Main 11.96s user 5.57s system 160% cpu 10.953 total
C на двух ядрах проваливает тест (поскольку точность страдает с любым компилятором). Зато ускоряется.
./a.out 10.63s user 0.02s system 195% cpu 5.438 total

Везде использован gcc 4.5.2, --march=native, без него C-код сливает в скорости (вариант bga_ не ускоряется от -march=native, но и без него достаточно быстрый).
./a.out 19.07s user 0.00s system 99% cpu 19.075 total ← с -O2
./a.out 10.63s user 0.00s system 99% cpu 10.642 total ← с -O2 -march=native.
-O3 и -ffast-math не меняют ничего при -march=native, без него:
./a.out 14.59s user 0.03s system 99% cpu 14.645 total
PGO у меня не меняет вообще ничего.
Java использует в ~22 раза больше RAM.
Замеры сделаны на athlon2 x2 250, 64 бита. YMMV.

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