Warsztat - Programowanie gier

Lipiec 30, 2010, 17:40:38 *
Witamy, Gość. Zaloguj się, lub zarejestruj proszę.

Zaloguj się podając nazwę użytkownika, hasło i długość sesji
Aktualności: Warsztat, Regulamin forum, #warsztat, Wiki, FAQ, NoPaste, Mapa
 
   Strona główna   Pomoc Szukaj Zaloguj się Rejestracja  
Strony: [1] 2 3 ... 15
  Drukuj  
Autor Wątek: C++, C# i Java - drobne porównanie wydajności  (Przeczytany 32518 razy)
revo
SuperHero Member
******

wiadomości: 1220


CLM


Zobacz profil WWW
« : Grudzień 03, 2007, 02:57:43 »

W związku z tematem Java kontra reszta świata postanowiłem zrobić małe porównanie wydajności C++, Java i C# na bardzo prostych testach. W poszukiwaniach gotowego testu trafiłem na http://www.irrlicht3d.org/pivot/entry.php?id=446, gdzie znajdował się test C++ vs Java 1.6. Delikatnie go przerobiłem (teraz jako parametr programu podaje się numer testu i nie wypisuje czasu). Czasy sprawdzałem za pomcą time na cygwinie. Musiałem tak zrobić, żeby ujednolicić testy, bo JIT z C# przedobrzał z optymalizacją i mimo faktycznego długiego działania program zwracał bardzo małe czasy wykonania.

Opis testów:

  • Fibonacci - liczy 44 liczbę fibbonaciego za pomocą wywołań rekurencyjnych
  • HeapSort - wykonuje sortowanie za pomocą kopcowanie na 5000000 doublach
  • Nested Loops - 4 zagnieżdżone pętle od 0 do 280 + proste działania zapobiegające optymalizacji
  • CopyData - ręczne skopiowanie 2000000 double z jednej do drugiej tablicy

Wszystkie programy dzielą niemal ten sam kod i nie są wprowadzane żadne optymalizacje charakterystyczne dla języka - nawet generator liczb losowych jest wbudowany w test, żeby zapewnić ten sam zestaw testowy i żeby nie polegać na tym z języka. Wynik testu jest całkiem ciekawy:



Tutaj można znaleźć skompilowane wersje jak i źródła.

Maszyna testowa to:

Intel Core 2 Duo 1.8 Ghz
2 GB Ram
Windows XP

Osobiście dla mnie wynik tego testu jest zaskoczeniem, bo spodziewałem się znacznie gorszych wyników Javy, która działała ociężale jak miałem z nią styczność prawie 3 lata temu. Teraz czas trochę zmienić poglądy. Wiadomo, że nie jest to życiowy test, ale pokazuje jak w prostych przypadkach maszyny wirtualne .Net i Javy sobie radzą. osobiście uważam, że nie jest źle, a przy dzisiejszych komputerach można w części zastosowań spokojnie poświęcić trochę wydajności na rzecz skróconego czasu produkcji - jak wiadomo czas to pieniądz, a za pieniądze można kupić lepszy sprzęt, który zrekompensuje nam różnice wydajności Smiley

Co wy o tym sądzicie? Jakie testy warto by było jeszcze zrobić?

Kod C++ był kompilowany w VC++ 2005 EE w trybie release z /O2 - jeśli ktoś ma wgrany intela, to chętnie dołożę skompilowaną nim wersję do zestawienia.
« Ostatnia zmiana: Grudzień 03, 2007, 03:04:17 wysłane przez revo » Zapisane

"We keep moving forward, opening new doors, and doing new things, because we're curious and curiosity keeps leading us down new paths", Walt Disney
Używasz Dev-C++? Przeczytaj. | Something yummy is coming...
Kamil Trzciński
Sr. Member
****

wiadomości: 325


Zobacz profil WWW
« Odpowiedz #1 : Grudzień 03, 2007, 03:57:07 »

Witam,

Wydaje mi się, że testy, które dotyczącą bezpośrednio nas, programistów, czyli operacje na wektorach/macierza. Jak i również może szybkość alokacji pamięci?

Pozdrawiam, Kamil Trzciński.
Zapisane
Xion
Member2000
*******

wiadomości: 2507



Zobacz profil WWW
« Odpowiedz #2 : Grudzień 03, 2007, 11:34:01 »

Ja bym jeszcze przetestował różnice w szybkości zarządzania pamięcią między metodą ręczną w C++ i GC w C#/Javie. Po prostu zaalokować te kilkadziesiąt tysięcy obiektów, usunąć je (a przy GC 'zgubić' do nich referencje) i stworzyć kolejnych kilkadziesiąt tysięcy nowych obiektów.
Zapisane

Anton Chigurh
Full Member
***

wiadomości: 145



Zobacz profil
« Odpowiedz #3 : Grudzień 03, 2007, 11:37:53 »

Możeby jeszcze potestować wbudowane kolekcje? listy, hasztejble itp. pod kątem wstawiania, wyszukiwania, usuwania itp.
Zapisane

postęp niniejszgo paska postępu : [|||||--------------]
kamykadze
Full Member
***

wiadomości: 184



Zobacz profil
« Odpowiedz #4 : Grudzień 03, 2007, 14:06:40 »

Szacunek - w końcu konkret w całej dyskusji -> masz ode mnie bonusa do karmy Smiley

Mam jedną prośbę - mógłbyś spróbować wykonać te same testy dla javy, ale uruchamiając maszynę wirtualną z przełącznikiem "-server" ? Java powinna w tej sytuacji zachowywać się jeszcze lepiej.

Pomysły poprzedników też wydają się ciekawe.
Zapisane
vashpan
SuperHero Member
******

wiadomości: 1599


Zobacz profil WWW
« Odpowiedz #5 : Grudzień 03, 2007, 16:51:36 »

Mnie za to dziwi praktycznie brak roznicy w wydajnosci miedzy .net 2.0 a 3.5... Czyzby MS spoczal na laurach ?

A takze inna sprawa - jak juz w tamtym temacie pisalem, wydaje mi sie ze takie testy nie sa do konca wiarygodne, gdyz dla tak malych projektow, tak naprawde maszyna wirtualna to skompiluje od razu i tyle. Czesto w ten sposob niektorzy sie chwala jaka to np. Java jest szybka.

Rzeczywiscie przydalby sie tez jakis test na liczbach zmiennoprzecinkowych.


Zapisane

Netrick
Full Member
***

wiadomości: 235

Debian GNU/Linux user


Zobacz profil
« Odpowiedz #6 : Grudzień 03, 2007, 18:01:53 »

Ludzie... Nie ma czegoś takiego jak szybkość języka programowania, jest szybkość kodu binarnego generowanego przez kompilator... Np. visual c++ tworzy wolniejszy kod niż mingw, a język ten sam!
Zapisane
revo
SuperHero Member
******

wiadomości: 1220


CLM


Zobacz profil WWW
« Odpowiedz #7 : Grudzień 03, 2007, 18:32:48 »

Dodałem programik, która uruchamia wszystkie testy na wszystkich programach, i mogę teraz łatwiej testować Wink

Idąc trochę za sugestiami dodałem jeszcze kolejne 4 testy:

Opis nowych:

  • Allocate - dynamicznie tworzymy tablicę tablic int'ów rozmiaru 4000000, a następnie wypełniamy ją dynamicznie stworzonymi tablicami po 10 int'ów
  • Collections List - tworzy szablonową listę, dodaje do niej liczby od 0 do 29999, a następnie sprawdza 30000 czy losowy element znajduje się w tablicy, około połowa testów daje wynik pozytywny
  • Collections Hashtable - tworzy szablonową tablice hashującą dla pary int'ów, dodajemy 3000000 par postaci <i,i>, a następnie  6000000 pytamy się o istnienie klucza, około połowa testów daje wynik pozytywny. Dla C++ użyto Map, dla C# Dictionary, a dla Javy Hashtable - mam nadzieje, że są to odpowiadające sobie kolekcje
  • Numeric - banalne obliczenia na doublach, a dokładniej:

Kod:
double a = 0;

for (int i=0; i<20000000; i++)
{
a += sin(i/1.111) + cos(i/2.222);
a += sqrt(a) + 1.1 * i / (i+10);
}

Co dziwi, to bardzo słaba wydajność Javy w ostatnim teście.

Po tym jak Netrick napisał o mingw, dodałem go do porównania - wypada blado, kompilowane z -O2. Netrick, proszę nie podawaj niesprawdzonych informacji - ten temat powstał właśnie po to, żeby walczyć z takimi mitami.

Ludzie... Nie ma czegoś takiego jak szybkość języka programowania, jest szybkość kodu binarnego generowanego przez kompilator...

Netrick - normalnie przyznałbym Ci rację, ale C# i Java działają na swoich maszynach wirtualnych i wyboru kompilatora nie masz - zatem prędkość maszyny wirtualnej jest tu równa prędkości języka.



Tutaj można znaleźć skompilowane wersje jak i źródła.

Ogólnie te testy nie mają za zadanie pokazać który język jest najlepszy, ale mają pokazać, że C# i Java wcale nie są takie wolne, jak je niektórzy postrzegają.
Zapisane

"We keep moving forward, opening new doors, and doing new things, because we're curious and curiosity keeps leading us down new paths", Walt Disney
Używasz Dev-C++? Przeczytaj. | Something yummy is coming...
naleth
Jr. Member
**

wiadomości: 80


Zobacz profil
« Odpowiedz #8 : Grudzień 03, 2007, 18:37:09 »

Jest to też o tyle ciekawe, że na The Computer Language Benchmarks Game wyniki są nieco inne. Wyniki C# mono w porównaniu do Javy są tutaj: http://shootout.alioth.debian.org/gp4sandbox/csharp.php. Oczywiście można powiedzieć, że co mono to nie to samo co maszynka Microsoft, ale na górze jest opcja do zmiany języka programowania, przy porównaniu C++ z Java 6 Server wyniki dość jednoznacznie wskazują C++ jako zwycięzcę. To samo z praktyki używania aplikacji napisanych w Javie można powiedzieć, że działają one znacznie wolniej od ekwiwalentnych aplikacji napisanych w C++.

Możesz przetestować podane tam programiki i zobaczyć, jaki będzie wynik u ciebie. Ja nie mam zbytnio takiej możliwości, w zasadzie mam w tej chwili na kompie tylko kompilator C++.
Zapisane
swiru
Gość
« Odpowiedz #9 : Grudzień 03, 2007, 19:57:06 »

A ja bym proponował dodać Fpc Smiley
Prosze.  Roll Eyes
Chciałbym zobaczyć jak się ma do reszty
Zapisane
revo
SuperHero Member
******

wiadomości: 1220


CLM


Zobacz profil WWW
« Odpowiedz #10 : Grudzień 03, 2007, 19:58:45 »

A ja bym proponował dodać Fpc Smiley
Prosze.  Roll Eyes
Chciałbym zobaczyć jak się ma do reszty

Ktoś by to musiał do paszczaka przepisać najpierw ;>
Zapisane

"We keep moving forward, opening new doors, and doing new things, because we're curious and curiosity keeps leading us down new paths", Walt Disney
Używasz Dev-C++? Przeczytaj. | Something yummy is coming...
kamykadze
Full Member
***

wiadomości: 184



Zobacz profil
« Odpowiedz #11 : Grudzień 03, 2007, 20:14:02 »




Kod:
double a = 0;

for (int i=0; i<20000000; i++)
{
a += sin(i/1.111) + cos(i/2.222);
a += sqrt(a) + 1.1 * i / (i+10);
}

Co dziwi, to bardzo słaba wydajność Javy w ostatnim teście.


Mam hipotezę, skąd tak zły wynik. W Javie domyślny typ zmiennoprzecinkowy to double. W C++ chyba float.
Przerobienie kodu na taki :

Kod:
double a = 0;

for (int i=0; i<20000000; i++)
{
a += sin(i/1.111f) + cos(i/2.222f);
a += sqrt(a) + 1.1f * i / (i+10);
}

pozwoliło mi zaoszczędzić kilkanaście procent (mierzyłem czas  przy użyciu System.curentTimeMillis()). Możesz spróbować, czy u Ciebie też to coś zmieni.



Zapisane
RageX
Gość
« Odpowiedz #12 : Grudzień 03, 2007, 20:29:49 »

Ja się słabo na tych bzdetach znam, więc... przejrzałem kod c#'owy.

Pewnych testów nie uważam za do końca wiarygodne, aczkolwiek nie mam pojęcia jak musiało by być aby było dobrze... do rzeczy:

CopyData
Kod:
ArraySize = 2000000

for (int k=0; k<100; ++k)
for (i=0; i<ArraySize; ++i)
target[i] = arr[i];
wg. mnie to tu za dużo iteracji, aby można było uznać że test dotyczy czystego kopiowania danych. O ile się nie mylę....w  C# ta druga pętla nie zostanie zoptymalizowana, a dotyczy ona bagatela 2000000 iteracji. Co zakrzywia nam test... proponowałbym raz a dobrze jeden duży blok przekopiować... moze structure z wypełnioną listą, co by być pewnym że kopiuje się pamięć, a nie procek pracuje na iteracjach. Moim zdaniem oczywiście. Podobnie się sprawa tyczy alokacji. Chociaż z drugiej strony używając struktur w c# pominie się GC, a to stworzy iluzje niewiarygodnie szybkiego c#. Ehh... nie wiem.

C# ma Hashtable. Dictionary jest implementacją hashtable'a. Nie wiem czy wolniejszą, ale to tak dla ścisłości.

Heh... nie podjąłbym się takiego testowania. Jest za dużo szczegółów, które czynią wyniki testów nie miarodajnymi. Wystarczą różne implementacje tych samych rzeczy i wszystko sie sypie. C# i Java, teoretycznie się z czasem optymalizują...
Mi wystarczy świadomość że C++>(o kilka procent)C#>>(znacznie)Java jeśli chodzi o wydajność. Po co mi więcej stresu. Smiley

/\
||
||
Całkiem dużym... musiałbyś na wszystkich platformach mierzyć dla floatów.
« Ostatnia zmiana: Grudzień 03, 2007, 20:35:48 wysłane przez RageX » Zapisane
Netrick
Full Member
***

wiadomości: 235

Debian GNU/Linux user


Zobacz profil
« Odpowiedz #13 : Grudzień 03, 2007, 21:03:49 »

revo:
Jest więc nieścisłość. Gcc to zestaw kompilatorów. Powiedz czy gcc dotyczy c czy c++ w twoim teście.

Cytuj
Po tym jak Netrick napisał o mingw, dodałem go do porównania - wypada blado, kompilowane z -O2. Netrick, proszę nie podawaj niesprawdzonych informacji - ten temat powstał właśnie po to, żeby walczyć z takimi mitami.

Zacznę od tego, że w moich testach g++ uzyskał wydajność o ok. 20% lepszą niż na visualu. Komputer ten sam, g++ pod linuxem, a visual pod windowsem. To nie jest mit tak jak twierdzisz. Tak więc nie uznawaj za mit prawdy.

Cytuj
Po tym jak Netrick napisał o mingw, dodałem go do porównania - wypada blado, kompilowane z -O2
W g++ w moich testach tylko dolinkowałem potrzebne libki, żadnych -O2. Może to przez to (nie wiem co to -o2 robi).

Cytuj
Netrick - normalnie przyznałbym Ci rację, ale C# i Java działają na swoich maszynach wirtualnych i wyboru kompilatora nie masz - zatem prędkość maszyny wirtualnej jest tu równa prędkości języka.

Przepraszam bardzo, ale pod linuxem jest alternatywny kompilator dla c# który generuje inny kod, no i maszyna wirtualna inna. Z tego co wiem (nie wiem czy to napewno prawda) jest kilka kompilatorów javy które generują kody o innych szybkościach, przynajmniej tak wyczytałem (w javie nie siedzę).
« Ostatnia zmiana: Grudzień 03, 2007, 21:16:53 wysłane przez Netrick » Zapisane
kamykadze
Full Member
***

wiadomości: 184



Zobacz profil
« Odpowiedz #14 : Grudzień 03, 2007, 21:09:12 »

Mam hipotezę, skąd tak zły wynik. W Javie domyślny typ zmiennoprzecinkowy to double. W C++ chyba float.

Domyslnym typem zmiennoprzecinkowym jest double. To znaczy zapis 10.5 interpretowany jest jako double. Wiec uzycie typu float byloby malym oszustwem Wink

W takim razie wycofuję się z hipotezy Tongue
Zapisane
Strony: [1] 2 3 ... 15
  Drukuj  
 
Skocz do:  

Hosting: Polska Strefa - Ogłoszenia
Powered by SMF 1.1.7 | SMF © 2006, Simple Machines LLC