Kategorie: Programowanie

Porównanie szybkości kilku języków programowania

Cześć! Cieszę się, że mnie odwiedziłeś/aś. Zanim przejdziesz do artykułu chciałbym zwrocić Ci uwagę na to, że ten artykuł był pisany kilka lat temu (2013-03-09) miej więc proszę na uwadzę że rozwiązania i przemyślenia które tu znajdziesz nie muszą być aktualne. Niemniej jednak zachęcam do przeczytania.

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

Nasze n = 100000

 

Czyli nasze programy będą szukały wszystkich liczb pierwszych z zakresu .

 

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!

Dzięki za wizytę,
Mateusz Mazurek
Mateusz M.

Pokaż komentarze

  • Dawidzie, mylisz się co do tego jak działa Java. Twój opis Javy odnosi się do Javy sprzed 20 lat. Obecnie Java jest językiem kompilowanym do zoptymalizowanego kodu maszynowego, podobnie jak C i C++. Różnica jest tylko w momencie, kiedy następuje ta kompilacja. W C i C++ kompilacja następuje w procesie budowania projektu, natomiast w Javie kompilacja jest podzielona na dwa etapy: w procesie budowania projektu następuje kompilacja do kodu posredniego, a w trakcie działania kod pośredni zostaje przetłumaczony na kod maszynowy. Po tym procesie maszyna wirtualna nie wprowadza żadnego narzutu - wykonuje się czysty kod maszynowy. Ponieważ w trakcie działania programu kompilator Javy ma więcej informacji niż kompilator C++, to kod wynikowy Javy może być lepiej zoptymalizowany niż kod C++ i w efekcie działać szybciej.

    Co do rzekomych benchmarków Google, to czytałem ten artykuł, i nie są to żadne badania Google, a jedynie zabawa kilku przypadkowych pracowników Google. Metodyka tych badań jest nieprawidłowa i wnioski są bezużyteczne, co przyznali sami autorzy kodu użytego w tamtym artykule. Np. pewne optymalizacje kodu C++ nie zostały zastosowane w kodzie Javy, mimo że nie było ku temu żadnego technicznego powodu. Już po publikacji artykułu kod Javy został poprawiony i miał szybkość taką samą jak kod C++.

  • A mnie taki kod w języku interpretowalnym kod działał mniej niż sekundę (i5-66000). Środowisko SML w TNTmips (program pisany C++);

  • Java, widzę że niektórym się nie podoba że jara wyszła na szybszą od C/C++. Java ogólnie jest szybsza od C/C++, ale ma dłuższy czas ładowania do pamięci (kod pośredni Javy w trakcie ładowania do pamięci jest kompilowany do kodu maszynowego) i Java zatrzymuje cały program w tekście czyszczenia pamięci. Pozostałe procesy mają bardzo podobną szybkość w Java i C/C++. Z pominięciem tego że w C/C++ czyszczenie pamięci działa cały czas co spowalnia program, ale to trzeba policzyć co się bardziej opłaca żeby kod działał cały czas trochę wolniej, czy też na jakiś czas się zatrzymywał. W tak robionym teście Java musiała wyjść szybciej, bo pomiar zaczął się po zastosowaniu do pamięci, a skończył przed czyszczeniem pamięci, a w przypadku C/C++ czyszczenie załapało się na pomiar.
    Zastanawia mnie wynik Python, bo tak samo jak Java jest językiem JIT więc powinien działać podobnie. Python też jest ładowany do pamięci w postaci kodu maszynowego, ale możliwe że gdy był robiony ten test Python był jeszcze językiem interpretowanym, a nie kompilowanym w trakcie wykonania.

    • Hej,
      dzięki za komentarza:)

      Test dla Pythona był robiony oczywiście CPython'em a on nie posiada JITa:)

  • Poradźcie w jakim języku programowania najlepiej napisać program do szybkiego przeliczania cyfr. Chciałbym zlecić program ale za bardzo nie wiem w jakim języku szukać mego zlecenia.

    • To chyba najlepszym rozwiązaniem będzie C/C++/Java - ale nie jestem ekspertem od tych języków. Ewentualnie jeśli naprawdę chce się Pythona, to numpy powinno dać radę.

  • Test jest błędny w pewnym zakresie.
    Aby można faktycznie porównaćszybkość nie wolno w C i C++ przydzielać dynamicznie pamięci.
    jest tutaj pewne niedociągnięcie gdyżjava jużma przydzielone miejsce a w przypadku C/C++ jest wołana funkcjaa. w efekcie wbrew zdrowemu rozsądkowi Java jest szybsza od C a logika wynikająca z działania interpretera bytecodu plasuje Javę nawet po C++

    • Jak najbardziej masz rację, w artykule zasygnalizowałem, żeby brać pod uwagę, że jest on średnio miarodajny:)

  • To jest test z na który jak widzętrzeba braćpoprawkę.
    Jest fizyczną niemożliwością by język kompilujący do native był wolniejszy od wirtualnej maszyny Java która prócz wykonywania kodu musi interpretować "w locie" bytekody.

Ostatnie wpisy

Podsumowanie roku 2025

Cześć! Lećmy z podsumowaniem roku. Książki To był bardzo nierówny rok. Zauważyłem, że czytam "falami", tzn że przez 3 tyg… Read More

3 miesiące ago

Python 1.0 vs. 3.13: Co się zmieniło?

Cześć. Dziś luźny artykuł, bo dziś pobawimy się jedną z pierwszy wersji Pythona. Skompilujemy go i zobaczymy co tam w… Read More

1 rok ago

Podsumowanie: styczeń i luty 2025

Nowy rok czas zacząć! Więc lećmy z podsumowaniem. Nowy artykuł Nie uwierzycie, ale pojawił się na blogu nowy artykuł! Piszę… Read More

1 rok ago

Just-in-time compiler (JIT) w Pythonie

Cześć! W Pythonie 3.13 dodano JITa! JIT, czyli just-in-time compiler to optymalizacja na która Python naprawdę długo czekał. Na nasze… Read More

1 rok ago

Podsumowanie roku 2024

Cześć! Zapraszam na podsumowanie roku 2024. Książki W sumie rok 2024 był pod względem ilości książek nieco podobny do roku… Read More

1 rok ago

Podsumowanie: wrzesień, październik, listopad i grudzień 2024

Podtrzymując tradycję, prawie regularnych podsumowań, zapraszam na wpis! Nie mogło obyć się bez Karkonoszy We wrześniu odwiedziłem z kolegą Karkonosze,… Read More

1 rok ago