Cześć.
Jakiś czas temu, gdy zaczynałem pisać pierwsze „Heloł łordy” zastanawiałem się który z tych wszystkich języków, jest najszybszy. Bo chyba własnie o szybkość pisania kodu/działania programu tu chodzi.
Teraz mam wystarczająco skilla żeby móc zmierzyć szybkość kilku języków implementując w nich ten sam algorytm w ten sam sposób. Prawie ten sam sposób. I zobaczyc na własne oczy.
Test ten przeprowadzę na kilku językach:
- PHP
Język do tworzenia stron WWW. Interpretowany. Można wykorzystwać go do pisania aplikacji okienkowych, ale jest to dość rzadka praktyka.
- Python
Ciekawy, interpretowany język programowania. Jego filozofią jest czytelność i przejrzystość kodu poprzez wymuszanie wcięć, które służą jako oznaczenia bloków kodu. Pojawił się w 91 roku, popularność zdobył zdecydowanie później.
- LUA
Jedyny język z tych przedstawionych przeze mnie gdzie indeksowanie tablic zaczyna się od 1 a nie od 0. Filozofią LUA jest „prostota, wydajność i przenośność kodu”.
- Java
Java :) jezyk programowania ogólnego przeznaczenia, wieloplatformowy. Uzywa swojej maszyny wirtualnej i dzięki temu może byc odpalony na każdym systemie który ma Javę zainstalowaną. W pełni obiektowy.
- C++
Klasyka.
- C
Klasyka klasyki :)
- Java Script
Język który służy przede wszystkim do tworzenia stron WWW. W przeciwieństwie od PHP jest wykonywany po stronie użytkownika a nie po stronie serwera.
Ok. Tyle słowem wstępu. Algorytmem którego czas wykonywania się będziemy mierzyć jest Sito Eratostenesa. Czemu ten algorytm? Ponieważ jest prosty w implementacji, dość praktyczny i złożonośc obliczeniona szałowa nie jest. Służy on do wyszukiwania liczb pierwszysch z przedziału <2; n>
Nasze n = 100000
Czyli nasze programy będą szukały wszystkich liczb pierwszych z zakresu <2; 100000>.
Ok, przedstawię listingi wraz z ilością znaków i linii.
PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 | <? $n=100000; for($i=0;$i<$n+1;$i++) $d[$i]=$i; for($a=2;$a<=$n+1;$a++) { for ($b=2*$a;$b<=$n+1;$b=$b+$a) { $d[$b]=0; } } ?> |
PHP kończy się na 13 liniach i 112 znakach bez spacji.
Python
1 2 3 4 5 | n =100000 e= range(2, n+1) for x in range(2, n+1): for t in range(x+x,n+1, x): e[t-2]=0 |
Python to tylko.. 5 linii i 72 znaki.
LUA
1 2 3 4 5 6 7 8 9 10 | n=100000 digits = {} for i=2,n do digits[i-1]=i end for i=2,n do for t=i+i,n, i do digits[t-1]=-1 end end |
Lua to 10 linii i 87 znaków.
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public static void main(String[] args) { int n=100000; boolean pierwsze[] = new boolean[n]; Arrays.fill(pierwsze, true); pierwsze[0]=false; pierwsze[1]=false; for(int i=2;i<=n;i++) { for(int t=i+i;t<n;t=t+i) { pierwsze[t]=false; } } } |
19 linii i 208 znaków.
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <iostream> #include <stdio.h> using namespace std; int main(){ bool* firsts=NULL; int n =100000; firsts = new bool[n]; int i; for( i=0;i<n;i++) firsts[i]=true; for(i=2;i<=n;i++){ for(int a=2*i;a<=n;a=a+i) firsts[a]=false; } delete[] firsts; return 0; } |
20 linii i 229 znaków.
C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include <stdio.h> int main(){ int* firsts; int n =100000; firsts = (int*)malloc(n*sizeof(int)); int i,a; for( i=0;i<n;i++) firsts[i]=1; for(i=2;i<=n;i++){ for( a=2*i;a<=n;a=a+i) firsts[a]=0; } free( firsts); return 0; } |
19 linii i 194 znaki.
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 | var n=100000; var d = new Array() for (var a = 2; a<n+1; a++) { d[a-2]=a } for (var i = 2; i <= n+1; i++) { for (var a = 2*i; a<=n+1; a=a+i) { d[a-2]=0 } } |
13 linii kodu i 118 znaków.
Ok. Kilka spraw organizacyjnych.
Cpp – kompilator g++ na win 7.
c- kompilator gcc na win 7.
Python – wersja 2.7
LUA – wersja 5.1.4
PHP – werjsa 5.2
JavaScript – na przeglądarce Google Chrome.
Java – wer. 7, NetBeans.
Mój komputer to HP 1,8GHz Core 2 Duo. 2 GB pamięci RAM. No i na nim Win 7.
Co dokładnie mierzyłem i w jaki sposób?
Mierzyłem samo wyszukiwanie liczb pierwszych bez wstepnego zapełniania tablicy czy zwalniania pamieci jak w przypadku C/Cpp. Mierzyłem czas ogólno dostępnymi funkcjami czyli np. dla PHP to funkcja microtime() a dla C to clock().
Wyniki badania sprowadziłem do jednej jednostki – milisekund.
Spójrzmy na wyniki…
Nr próbki | 1 | 2 | 3 | 4 | 5 | Średnia | |
PHP | 210 | 160 | 240 | 200 | 190 | 200 | [miliseconds] |
Python | 783 | 695 | 962 | 709 | 714 | 772,6 | [miliseconds] |
LUA | 246,01 | 244,01 | 249,01 | 243,02 | 231 | 242,61 | [miliseconds] |
Java | 9 | 9,5 | 8,7 | 9,3 | 9,8 | 9,26 | [miliseconds] |
Cpp | 15 | 16 | 31 | 16 | 15 | 18,6 | [miliseconds] |
C | 13 | 12 | 9 | 12 | 11 | 11,4 | [miliseconds] |
JavaScript | 36 | 35 | 34 | 41 | 37 | 36,6 | [miliseconds] |
Co w przełożeniu na wykres wygląda tak:
Uff, co się okazuje? Ano okazuje się że nie możemy mieć wszystkiego. Python jako język który miał najmniejszą ilość linii i znaków okazał się najwolniejszy. LUA, prawie 3 krotnie szybsza jest od Pythona a różnica w ilości linii znikoma.
Zobaczmy dokładnie jak przedstawia się ilość linii do szybkosci:
Średnia | Linii | |
PHP | 200 | 13 |
Python | 772,6 | 5 |
LUA | 242,61 | 10 |
Java | 9,26 | 19 |
Cpp | 18,6 | 20 |
C | 11,4 | 19 |
JavaScript | 36,6 | 13 |
Uzupełnijmy tabelę o kolumnę która będzie stworzona z podzielenia średniego czasu przez ilość linii:
Średnia | Linii | Średnia / Ilość linii | |
PHP | 200 | 13 | 15,38461538 |
Python | 772,6 | 5 | 154,52 |
LUA | 242,61 | 10 | 24,261 |
Java | 9,26 | 19 | 0,487368421 |
Cpp | 18,6 | 20 | 0,93 |
C | 11,4 | 19 | 0,6 |
JavaScript | 36,6 | 13 | 2,815384615 |
Wspólczynnik który stworzyliśmy powinien być jak najmniejszy. Sortując wg niego, otrzymujemy:
- Java
- C
- C++
- JavaScript
- PHP
- LUA
- Python
Co z tego wynika? Chociażby to że warto pisać w Javie ;) A tak serio, bardzo blisko Javy jest C i C++ – nie bedzie powodu one się tam znalazły. To jedne z szybszych języków jakie istnieją. Czemu tutaj Java okazała się szybsza? Bo mimo wszystko ona się dalej rozwija i twierdzenie że jest baaardzooo wooolnaaaa powoli, powoli.. Staje się nieaktualne. Nie twierdzę że jest super szybka, ale dodając do wyników fakt przenośności kodu, pełną obiektowość i multum klas dostępnych w Internecie – stawia Jave dość wysokow. PHP, LUA, Python – wielcy przegrani. Mimo że każdy z tych języków jest dobrym językiem (PHP dobre moge nazwać od wersji 5) to tracą na szybkosci przez interpretowany charakter. LUA jest średnio popularnym językiem, PHP się używa do stron, a co do Pythona.. Mimo tego że wolny, to nadal warty uwagi, chociażby na słynne 5 linii :)
Warto wspomnieć – test nie jest jakoś bardzo miarodajny – różnych języków używa się do różnych zastosowań. Zbadanie jednego alogrytmu nie powinno określać całej efektywności danego języka.
Pozdrawiam!
Mateusz Mazurek