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ę.

Ostatnie wpisy

Podsumowanie: luty i marzec 2024

Ostatnio tygodnie były tak bardzo wypełnione, że nie udało mi się napisać nawet krótkiego podsumowanie. Więc dziś zbiorczo podsumuję luty… Read More

4 tygodnie ago

Podsumowanie: styczeń 2024

Zapraszam na krótkie podsumowanie miesiąca. Książki W styczniu przeczytałem "Homo Deus: Historia jutra". Książka łudząco podoba do wcześniejszej książki tego… Read More

3 miesiące ago

Podsumowanie roku 2023

Cześć! Zapraszam na podsumowanie roku 2023. Książki Zacznijmy od książek. W tym roku cel 35 książek nie został osiągnięty. Niemniej… Read More

4 miesiące ago

Podsumowanie: grudzień 2023

Zapraszam na krótkie podsumowanie miesiąca. Książki W grudniu skończyłem czytać Mein Kampf. Nudna książka. Ciekawsze fragmenty można by było streścić… Read More

4 miesiące ago

Praca zdalna – co z nią dalej?

Cześć, ostatnio w Internecie pojawiło się dużo artykułów, które nie były przychylne pracy zdalnej. Z drugiej strony większość komentarzy pod… Read More

4 miesiące ago

Podsumowanie: listopad 2023

Zapraszam na krótkie podsumowanie miesiąca. Książki W listopadzie dokończyłem cykl "Z mgły zrodzony" Sandersona. Tylko "Stop prawa" mi nie do… Read More

5 miesięcy ago