Wydajność JavaScriptu vs inne języki

Postanowiłem przetestować i porównać wydajność JavaScriptu, przy okazji porównując go do innych języków, które miałem pod ręką (C#, C++ i PHP).

Z przeglądarek chciałem przetestować Operę, IE, Chrome i Firefoksa w najnowszej wersji stabilnej, w wersji testowej oraz sprzed kilku lat, ale nie wszystkie te wersje udało mi się znaleźć w sieci.

Wykorzystam tutaj kod generujący ciąg Fibonacciego (więcej do przeczytania o nim na Wikipedii ). Kod ten wykorzystuje wielokrotnie rekurencję.

Testy przeprowadziłem na laptopie z procesorem Intel Core i5 480M, 3GB DDR3 i systemem Windows 8 x64.

Kod

Użyty kod Javascript:


function fib(n)
{
	if(n==0)
		return 0;
	else if(n==1)
		return 1;
	else if(n>=2)
		return fib(n-1)+fib(n-2);
}
function ciag(n)
{
	var czas=new Date();
	var lista=[];
	for(var z=0;z<=n;z++)
	{
		lista[z]=fib(z);
	}
	return (new Date())-czas;
}

Kod PHP


function fib($n)
{
	if($n==0)
		return 0;
	else if($n==1)
		return 1;
	else if($n>=2)
		return fib($n-1)+fib($n-2);
}
function ciag($n)
{
	
	$a=explode(' ', microtime());
	$czas=($a[0]+$a[1])*1000;
	for($z=0;$z<=$n;$z++)
	{
		$lista[$z]=fib($z);
	}
	$a=explode(' ', microtime());
	return($a[0]+$a[1])*1000-$czas;
}

Kod C#


static ulong fib(int n)
{
	if (n == 0)
		return 0;
	else if (n == 1)
		return 1;
	else if (n >= 2)
		return fib(n - 1) + fib(n - 2);
	else
		return 0;
}
static double ciag(int n)
{
	var czas = DateTime.Now;
	var lista = new ulong[n + 1];
	for (var z = 0; z <= n; z++)
	{
		lista[z] = fib(z);
	}
	return (DateTime.Now - czas).TotalMilliseconds;
}

Kod C++

#include <windows.h>
static unsigned long long fib(int n)
{
	if (n == 0)
		return 0;
	else if (n == 1)
		return 1;
	else if (n >= 2)
		return fib(n - 1) + fib(n - 2);
	else
		return 0;
}
static DWORD ciag(int n)
{
	DWORD czas = GetTickCount();
	unsigned long long lista[41];
	for (int z = 0; z <= n; z++)
	{
		lista[z] = fib(z);
	}
	 return GetTickCount() - czas;
}

Kod C++ dla .NET (inny sposób mierzenia czasu)

static unsigned long long fib(int n)
{
    if (n == 0)
        return 0;
    else if (n == 1)
        return 1;
    else if (n >= 2)
        return fib(n - 1) + fib(n - 2);
    else
        return 0;
}
static double ciag(int n)
{
	DateTime czas = DateTime::Now;
    unsigned long long lista[41];
    for (int z = 0; z <= n; z++)
    {
        lista[z] = fib(z);
    }
    return (DateTime::Now - czas).TotalMilliseconds;
}

Oczywiście kod ten można zoptymalizować i to dość znacznie, ale wtedy wykonuje się zbyt szybko żeby ten czas można było porównać.

Wyniki

Czasy były mierzone po kilka razy i uśredniane, ale pomiary nie różniły się między sobą o więcej niż kilka procent.

Wnioski


  • Najszybszym językiem jest natywny c++ 64 bitowy
  • Natywny 32 bitowy c++ jest wolniejszy prawie 11 razy od 64 bitowego, jest też wolniejszy od 32 bitowego c++ pod .NET
  • W .NET c# jest szybszy od c++ (31% w wersji 32 bitowej, wersji 64 bitowej nie udało mi się skompilować)
  • JavaScript może być wydajnym językiem (Firefox Nightly tylko 2 razy wolniejszy od c++), ale nie musi (Firefox 3.6 ponad 64 razy wolniejszy od c++). Mamy tutaj bardzo szybki wzrost wydajności wraz z rozwojem przeglądarek (porównaj Firefoksa 3.6, 22 i 25 nightly).
  • PHP jest bardzo wolny (152 razy wolniejszy od c++)