[update: 15/01/2010 - okazało się, że pomiary dla C# były źle przeprowadzane co zaniżało jego wydajność mniej więcej o 10 razy!!!! Błędnie użyłem DateTime.Now.Ticks zakładając, że zwraca ilość naonsekund, a zwraca ilość ticków, których w nanosekundzie mieści się dziesięć. Niestety nikt tego wcześniej nie zauważył i złe wyniki poszły w świat. [tytuł posta też zmieniony ;-)]]
Nowe wyniki prezentują się tak [wyniki dla procesora Intel Core 2 Duo T6600 2.20 GHz [2 rdzenie 64 bitowe pod 64 bitowym Windows 7]:
C# z .NET 4.0 - 1.17 ms
Java 1.5 z przełącznikiem -server - 1.096 ms
Java 1.6 z przełącznikiem -server - 2.8895 ms
Python 2.6 - 10.88 ms
Z radością jednak odnotowuję, że słuszne były moje przewidywania i słuszne zdziwienie słabym wynikiem C# :-) szkoda tylko, że wszystkiemu winien był taki błąd :-)
[update: 23/10/2009 - dodałem informacje o wynikach programu w C i parę uwag]
Tak nie miałem pomysłu na to co dziś napisać ;-) więc zrobiłem sobie szybki test co jest szybsze [w obliczeniach] Java, Python czy C#, kontrolnie postanowiłem dodać też C :-).
Przyznam, że z języków wykonywanych w wirtualnych maszynach stawiałem na C#.
W każdym z języków napisałem program, którego celem było policzenie numerycznie 1000 razy całki oznaczonej w przedziale od -10 do 10 [niedomkniętym z prawej] w 10000 krokach z funkcji:
f(x)=e-x2Wynikiem jest coś bliskiego pierwiastkowi z liczby pi [swoją drogą to była rzecz na analizie matematycznej która mnie zachwyciła, całka z funkcji w której użyta jest
e, a wynikiem jest pierwiastek z pi, czyli istnieje związek między niektórymi stałymi matematycznymi... może to zrobiło na mnie takie wrażenie bo byłem wtedy świeżo po czytaniu Kontaktu Carla Sagana? :-)].
No i wyniki wyglądają tak [wszystkie czasy dla pojedynczego policzenia całki]:
.
| Język/Procesor | AMD Turion64 ML-30* | Intel Core Duo 2.16 GHz | Celeron 900 MHz [Asus EEE] | .
| C | b/d | 4 ms | 4 ms | .
| Java | 18 ms | 10 ms | 10 ms | .
| C# [wyniki powinny zostać prawdopodobnie podzielone przez 10 z racji błędu w programie testowym] | 45 ms | 32 ms | 34 ms | .
| Python | 60-74 ms** | 27 ms | 30.5 ms |
|
Przyznam, że byłem zaskoczony. Przed uruchomieniem testów dałbym sobie rękę obciąć za to, że z języków wykonywanych przez maszyny wirtulane wygra C#, bo coś mi się po głowie kołatało, że .NET swobodnie korzysta z koprocesora [kto jeszcze pamięta co to jest? ;-) ja pamiętam, że moją przygodę z PC zaczynałem na komputerze bez koprocesora i że były nawet softwareowe emulatory tegoż :-)], czego Java nie może robić bo jej matematyka zmiennoprzecinkowa nie jest do końca zgodna z tą stosowaną w x86 [dla pewności w przypadku Java'y uruchomiłem jeszcze test z arytmetyką zgodną ze strictfp, i wtedy czas jednej iteracji to 20 ms dla Turiona 64].
A tu proszę, Java okazała się w tym przypadku 2.5-3 raza szybsza od C# :-) i 2.85 do 3.33 razy szybsza od Pythona [testy z Pythonem 3000, czy może 3.1? pokazują, że Python troszkę przyśpieszył].
Do testów użyłem Sun Java 1.6.0_15 [czyli chyba najnowszej], dla Pythona był to ActiveState Python 2.5 i oryginalny Python 2.5 z Python.org, w przypadku .NET użyłem wersji 3.5 z włączoną optymalizacją.
Programy wyglądały tak [umieszczam tylko funkcje obliczające całkę, N=10000, kody źródłowe i wersje skompilowane znajdziecie w
archiwum, chętnie poznam Wasze wyniki :-)].
Java:
static double calc() {
double sum = 0;
for (int i=0; i<N; i++) {
double x = 20.0*i/N-10.0;
sum+=Math.pow(Math.E, -x*x)*(20.0/N);
}
return sum;
}
C#:
static double calc() {
double sum = 0;
for (int i = 0; i < N; i++) {
double x = 20.0f * i / N - 10.0f;
sum += Math.Pow(Math.E, -x * x) * (20.0 / N);
}
return sum;
}
Python:
def calc():
sum=0
for i in range(0,N):
x=20.0*i/N-10
sum=sum+math.e**(-x**2)*(20.0/N)
return sum
C:
double calc() {
int i;
double sum = 0;
for(i=0; i<N; i++) {
double x = 20.0*i/N-10.0;
sum+=pow(M_E, -x*x)*(20.0/N);
}
return sum;
}
Przyznam, że jestem pozytywnie zaskoczony wynikiem Java'y :-)
Jest co prawda wolniejsza od C, ale "tylko" o 2.5 raza, w przypadku C vs. C# mamy różnicę prawie 1 rzędu w wydajności, a to już coś.
Wszystkie testy odbywały się na moim laptopie, z procesorem Turion 64ML-30 1.6 GHz ściętym do 800 MHz.
Jak komuś się będzie chciało to prosiłbym o Wasze wyniki :-)
* Turion 64ML-30 o nominalnym taktowaniu do 1.6 GHz, ale softwareowo "obcięty" do 800 Mhz
** ActivePython wydaje się być wolniejszy od "oryginalnego" Pythona.Podobne postybetaRaspberry Pi to nie jest demon prędkości ;-)Całkujący Dart ;-)Plus dla Scala, minus dla Groovy ;-)A JavaScript i tak szybszy ;-)Język Go dla Windows :-)