LINUX.ORG.RU
ФорумTalks

Братцы! А я Java то оказывается тормоз! :0


0

0

Решил проверить производительность популярных виртуальных машин. Тестировал Microsoft .Net, Mono и Java. Дал им банальнейшую задачу, в которой написал как можно более низкоуровневый код, дабы измерить чистую убыль производительности. Программа сто миллионов раз резервирует память для матрицы 3x3, заполняет ее случайными числами и считает определитель. Вот код на Java (на C# почти тоже самое):

import java.util.Random;

class test
{
public static void main(String [] args)
{
int a[][];
int k,m,j,det;
Random random = new Random();
for(j = 0; j<100000000; j++)
{
a = new int[3][3];
for(k=0; k<3; k++) for(m=0; m<3; m++) {a[k][m] = random.nextInt();}
det = a[0][0]*a[1][1]*a[2][2]+a[0][1]*a[1][2]*a[2][0]+a[0][2]*a[1][0]*a[2][1]*-
a[0][2]*a[1][1]*a[2][0]-a[0][1]*a[1][0]*a[2][2]-a[0][0]*a[1][2]*a[2][1];
}
}
}

Аналогичный код на СИ (выполнялся минуту):

#include <stdlib.h>

int main()
{
int* a;
int k,m,j,det;
for(j = 0; j<100000000; j++)
{
a = (int*) malloc(9*sizeof(int));
for(k=0; k<3; k++) for(m=0; m<3; m++) {*(a+3*k+m) = rand();}
det = (*(a+3*0+0))*(*(a+3*1+1))*(*(a+3*2+2))+(*(a+3*0+1))*(*(a+3*1+2))*(*(a+3*2+0))+(* (a+3*0+2))*(*(a+3*1+0))*(*(a+3*2+1))*-
(*(a+3*0+2))*(*(a+3*1+1))*(*(a+3*2+0))-(*(a+0+3*1))*(*(a+3*1+0))*(*(a+3*2+2))-(* (a+3*0+0))*(*(a+3*1+2))*(*(a+3*2+1));
free(a);
}
return 0;
}

(просьба не бить меня за то, как я работаю с двумерными массивами на Си ;) )

Результаты печальны: первое место.... Microsoft! Всего в полтора раза медленне Си (одна минута, тридцать секунд). Далее жаба - две минуты. И инвалид Mono - 2 мин 45 с. Запуск Явы в с ключем -server не помог. Не хорошо как-то. Может это просто MS жульничает? Все-таки тесная интеграция с ОС... Незнаю... :( Попробуйте кто-нибудь у себя, мож другие цифры будут.

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

> то ли в Рио

Я знал что О.Бендер что-то недоговаривал, а то все негры... в белых штанах...

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

CL-USER> (defun make-random-matrix ()
	   (declare (optimize (speed 3)))
	   (let ((m (make-array '(3 3) :element-type 'single-float)))
	     (dotimes (i 3)
	       (dotimes (j 3)
		 (setf (aref m i j) (random 1.0))))
	     m))
CL-USER> (defun det (m)
	   (declare (optimize (speed 3)))
	   (declare (type (simple-array single-float (3 3)) m))
	   (- (+ (* (aref m 0 0) (aref m 1 1) (aref m 2 2))
		 (* (aref m 0 1) (aref m 1 2) (aref m 2 0))
		 (* (aref m 0 2) (aref m 1 0) (aref m 2 1)))
	      (* (aref m 0 2) (aref m 1 1) (aref m 2 0))
	      (* (aref m 0 1) (aref m 1 0) (aref m 2 2))
	      (* (aref m 0 0) (aref m 1 2) (aref m 2 1))))
CL-USER> (defun test ()
	   (declare (optimize (speed 3)))
	   (dotimes (i 1000000)
	     (det (make-random-matrix))))
CL-USER> (time (test))
Evaluation took:
  4.323 seconds of real time
  2.16 seconds of user run time
  0.08 seconds of system run time
  [Run times include 0.608 seconds GC run time.]
  0 calls to %EVAL
  0 page faults and
  96,000,120 bytes consed.


max@triton:~/ > cat /proc/cpuinfo
processor       : 0
cpu             : 750FX
temperature     : 42-46 C (uncalibrated)
clock           : 800.000000MHz
revision        : 2.2 (pvr 7000 0202)
bogomips        : 49.53
timebase        : 24835213
platform        : PowerMac
machine         : PowerBook4,3
motherboard     : PowerBook4,3 MacRISC2 MacRISC Power Macintosh
detected as     : 257 (iBook 2 rev. 2)
pmac flags      : 0000001b
L2 cache        : 512K unified
pmac-generation : NewWorld

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

Хмм, сейчас сделал количество итераций 100000000, sbcl запустил из консоли (было в SLIME):

time (test))

Evaluation took:
  373.243 seconds of real time
  174.928 seconds of user run time
  5.68 seconds of system run time
  [Run times include 15.968 seconds GC run time.]
  0 calls to %EVAL
  0 page faults and
  9,600,006,160 bytes consed.

Begemoth ★★★★★
()

> (просьба не бить меня за то, как я работаю с двумерными массивами на Си ;) )

Мда... мисье явно знает толк в извращениях.

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

У меня получилось для 
С ~95 секунд,
SPForth: ~36 секунд.
WINAPI: GetTickCount KERNEL32.DLL
DECIMAL
0 VALUE det
0 VALUE mem
0 VALUE t1
: bench
        GetTickCount TO t1
        36 ALLOCATE THROW TO mem
        100000000  0 DO
                        2 0 DO 2 0 DO
                                I 3 * J + mem OVER + !
                        LOOP LOOP

                        mem @
                        mem 16 + @ *
                        mem 32 + @ *

                        mem 4 + @
                        mem 20 + @ *
                        mem 24 + @ *

                        mem 8 + @
                        mem 12 + @ *
                        mem 28 + @ *
                        + +

                        mem @
                        mem 16 + @ *
                        mem 32 + @ *

                        mem 4 + @
                        mem 20 + @ *
                        mem 24 + @ *

                        mem 8 + @
                        mem 12 + @ *
                        mem 28 + @ *
                        + +

                        *   TO det
              \  DEPTH . CR
              \  mem 36 DUMP CR
        LOOP
        mem FREE THROW
         GetTickCount t1 - 1000 / . ."  s" CR
       ." Stop" CR
        ;
 bench

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

>Что си быстрее? Как думаешь тут есть люди которые с этим не согласятся?

Естественно фортранисты не согласяться ;)))

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

>Питона ещё никто не тестировал?

Я протестировал :D Незабываемое ощущение! Вот серс:

import random

print "LOL started\n"

for j in range(100000000):
a = [[random.randint(0,100),random.randint(0,100),random.randint(0,100)],[random.ran dint(0,100),random.randint(0,100),random.randint(0,100)],[random.randint(0,100), random.randint(0,100),random.randint(0,100)]]
det = a[0][0]*a[1][1]*a[2][2]+a[0][1]*a[1][2]*a[2][0]+a[0][2]*a[1][0]*a[2][1]*-a[0][2] *a[1][1]*a[2][0]-a[0][1]*a[1][0]*a[2][2]-a[0][0]*a[1][2]*a[2][1]
print "EOL\n"

Сначала он почти намертво вешает Linux, съедает ВЕСЬ свеп и уже через полторы минуты выдает странное сообщение 'Killed' и завершается :)))

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

>optimize (speed 3)

Это что за шаманство?

У меня этот вариант даёт:

Evaluation took:
0.832 seconds of real time
0.620038 seconds of user run time
0.204013 seconds of system run time
0 page faults and
95,996,528 bytes consed.

А с 100м итераций:
77.017 seconds of real time
59.643726 seconds of user run time
17.221075 seconds of system run time
0 page faults and
9,600,023,392 bytes consed.

Athlon XP 2k+ (1660MHz)

:)

2xTERM
>Сначала он почти намертво вешает Linux, съедает ВЕСЬ свеп и уже через полторы минуты выдает странное сообщение 'Killed' и завершается :)))

А что, если через каждые 10к итераций делать gc.collect()?

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

>Сначала он почти намертво вешает Linux, съедает ВЕСЬ свеп и уже через полторы минуты выдает странное сообщение 'Killed' и завершается :)))

Еще одно доказательство, что Python язык для обучения, а не для реальных задач.

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

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

Еще одно доказательство, что Python язык для обучения, а не для реальных задач.

ну не так это. Своя ниша у питона есть. И не надо ему давать зубодробительные задачи. Вы же не чистите зубы шреддером. Хотя кто вас знает.

GobZ
()

Кто там хотел баша ? ;))


#!/bin/bash
declare -i num_iter=$1
bash_bench() {              
 declare -i k
 declare -i m
 declare -i j=0
 while [ $j -lt $num_iter ]
 do
  k=0
  while [ $k -lt  3 ]
  do
   m=0
   while [ $m -lt  3 ]
   do
   declare -i idx=$k*3+$m
   a[$idx]=$RANDOM
   m=$m+1
   done
  k=$k+1
  done
# echo  ${a[0]} ${a[1]} ${a[2]}
# echo  ${a[3]} ${a[4]} ${a[5]}
# echo  ${a[6]} ${a[7]} ${a[8]}
 declare -i det=${a[0]}*${a[4]}*${a[8]}+${a[1]}*${a[5]}*${a[6]}+${a[2]}*${a[3]}*${a[7]}-${a[
2]}*${a[4]}*${a[6]}-${a[1]}*${a[3]}*${a[8]}-${a[0]}*${a[5]}*${a[7]}
# echo  $det
 j=$j+1
# echo -ne  $j/$num_iter\\r 
 done     
}          
 
if [ "$1" != "" ]
then
time bash_bench 
else
echo Usage: $0 [num_iter]
fi

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

>Похоже Питон решил, что не справится и предпочел харакири позору.

Спокойно, без паники.

$ cat test.py from time import time,localtime,asctime from random import randint r=lambda: randint(0,10)

def det(a): return a[0][0]*a[1][1]*a[2][2]+a[0][1]*a[1][2]*a[2][0]+ a[0][2]*a[1][0]*a[2][1]+a[0][2]*a[1][1]*[2][0]-a[0][1]*a[1][0]*a[2][2]-a[0][0]*a [1][2]*a[2][1] def test(): i=0 a=[[r(),r(),r()],[r(),r(),r()],[r(),r(),r()]] while(i<100000000): det(a) i+=1

print asctime(localtime(time())) test() print asctime(localtime(time()))

python test.py Sat May 5 16:15:05 2007 Sat May 5 16:24:34 2007

Итого, 9,5 минут. Как видите, не так-то всё и плохо :)

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

> Я протестировал :D Незабываемое ощущение!

Любой, кто хоть немного знаком с Python, написал бы xrange.

Что там Саныч говорил про дверь?

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

>>optimize (speed 3)

>Это что за шаманство?

это указание (пожелание) компилятору оптимизировать прогу по скорости (выкинуть лишние проверки типов, арифметику писать машинными командами, а не call generic-{+,*}). Может еще стоило указать (safety 0)

Begemoth ★★★★★
()

Вообще, тест никуда не годится. Надо делать как общие так и отдельные тесты для языков с GC и без него. И отдельно тестировать арифметические тесты и тесты на управление памятью. К тому же приводить оптимизированные версии тестов, учитывающие особенность конкретного языка (реализации).

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

> отдельные тесты для языков с GC и без него.

Зачем ? Если GC - расплата за парадигму ?

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

>Еще одно доказательство, что Python язык для обучения, а не для реальных задач.

>ну не так это. Своя ниша у питона есть. И не надо ему давать зубодробительные задачи. Вы же не чистите зубы шреддером. Хотя кто вас знает.

На Питоне много чего пишут щас, например, Al в игрушках. Или вот например - http://www.q-lead.com/ Часть на Питоне, критические участки - на с++ Можно сказать не тормозит, на гиге оперативы и 3 гГц проце... Хотя я думал, что для подобных задач нужен минимум кластер...

DNA_Seq ★★☆☆☆
()

Слово Java в сабже лишнее;) Исправьте пожалуйста.

anonymous
()

Низачот. Ну, а теперь посмотри внимательно на свой "код" и узнай, где ты облажался. Рановато тебе пока в Джава-программисты идти. Если сам не додумаешься, Брюса А.Тейта почитай. Или у иблиса спроси, он у нас шибко грамотный.

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

>Еще одно доказательство, что Python язык для обучения, а не для реальных задач.

Python просто так не сдаётся!

>>> from test import test
>>> from time import time,localtime,asctime
>>> asctime(localtime(time()))
'Mon May 7 02:09:19 2007'
>>> test()
0
>>> asctime(localtime(time()))
'Mon May 7 02:10:24 2007'

Итого всего лишь 1 минута :)

seiken ★★★★★
()

Очень бы хотелось посмотреть на тесты где работает несколько
процссов и происходит частое переключение из режима ядра в пользовательский...
как тогда будет ява работать???

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

>Низачот. Ну, а теперь посмотри внимательно на свой "код" и узнай, где ты облажался. Рановато тебе пока в Джава-программисты идти.

Если ты про new, то так было задумано. Потом я проводил тест и без new.

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

>Если ты про new, то так было задумано. Потом я проводил тест и без new.

А ты уверен, что new в Джаве дорого стоит?

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

> def test(): i=0 a=[[r(),r(),r()],[r(),r(),r()],[r(),r(),r()]] while(i<100000000): det(a) i+=1

Низачот. Массив надо заполнять на каждой итерации. С учётом этого - расползается до ~30 минут.

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

> for j in range(100000000):

Мля, ну хто ж так тестит?!

for j in xrange(100000000):

> Сначала он почти намертво вешает Linux, съедает ВЕСЬ свеп и уже через полторы минуты выдает странное сообщение 'Killed' и завершается :)))

Естессно. Ибо ни один комп не выдержит выделения 4 Гиг памяти чисто на поиграццо.

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

> Еще одно доказательство, что Python язык для обучения, а не для реальных задач.

Это еще одно доказательство, что умеючи можно и член сломать...

Кста, я в предыдущем посте соврамши немного -- не 4 Гига, а 400-600 метров. Более разумно, но все равно тяжко.

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