Nevim jestli nekde delam chybu, ale dost me zklamala rychlost vysledneho kodu Erlangu OTP 17.1 (i R16).
Trivialni priklad pro vypocet n-teho clenu Fibonacciho rady:
fib(N) -> fib(N,0,1).
fib(0,Res,_) -> Res;
fib(N,Res,Next) when N > 0 -> fib(N-1, Next, Res+Next).
Kompilace s max. optimalizaci:
erlc +native +"{hipe, [o3]}" fib_test.erl
time erl -smp enable -noshell -run fib_test main 1000000
real 0m12.558s
Srovnavaci verze v Pythonu:
def fibIter(n):
if n < 2:
return n
a, b = 1, 1
for num in xrange(2, n):
a, b = b, a+b
return n
time python-2.7 fib_test.py 1000000
real 0m13.260s
U Erlangu jsem ocekaval jsem vyrazne lepsi vysledek nez u dynamickeho a interpretovaneho pythonu. Ma hur optimalizovanou aritmetiku s BigInt ? Nevhodna implementace funkce fib ? Analytickou verzi samozrejme znam, ale srovnavam jablka s jablkama. Naivni rekurzivni neskonci ani za 20 minut.
Napr. nasledujici rekurzivni verze v Haskellu prelozena s ghc -O2 spocita milion clenu za cca 5 s na stejnem stroji.
fib = 1 : 1 : zipWith' (+) (init fib) (tail fib)
where
zipWith' fn (!x:xs) (!y:ys) = fn x y : zipWith' fn xs ys
zipWith' _ _ _ = []
http://erlang.org/pipermail/erlang-questions/2010-October/054183.html
http://erlang.org/pipermail/erlang-questions/2010-October/054191.html
Šlo by na bigint použít toto?
fib(N) -> fib(N,0,1).
fib(0,Res,_) -> Res;
fib(N,Res,Next) when is_number(N) andalso is_number(Res) andalso is_number(Next) andalso N > 0 -> fib(N-1, Next, Res+Next).
Porovnání rychlosti aritmetiky sekvenčního programu v různých jazycích.
http://benchmarksgame.alioth.debian.org/u64/performance.php?test=nbody#about
Erlang je asi dobrý jen v tom, na co ho Ericsson potřeboval - fault tolerance, message passing concurrency a bit syntax. Na telefonních ústřednách výpočty neběží. :/
Ono je to někdy něco za něco. Masivně paralelní systémy bývají běžně i řádově pomalejší než sekvenční systémy. Tedy jen dokud sledujete "výkon na výpočetní uzel". Pokud těch uzlů spustíte stovky, tak pak se to otočí.
Erlang vypadá jako prostředí, kde by režie na paralelní běh mohla mít nižší složitost. Obecně je "celkový výkon" v závislosti na počtu uzlů křivka logaritmická. Bylo by zajímavé vědět, jestli pro nějaké typy úloh dosahuje Erlang výrazného zlepšení (delší úsek linearity apod.)
Erlang nikdy nebyl koncipovany na number crunching a ve vsech materialech se zduraznuje, ze by to nej nemel byt pouzivan, protoze neni efektivni.
> U Erlangu jsem ocekaval jsem vyrazne lepsi vysledek nez u dynamickeho a interpretovaneho pythonu.
Proc? Ten bytekod, do ktereho se pythonni program prelozi, bude nejspis hodne podobny tomu erlangovskemu, tam moc neni co vymyslet...
Tyhle testy na rychlost jednoduchych algoritmu vypovidaji jenom malo o realne pouzitelnosti. Staci si predstavit, ze mam nejaky velky system sestavajici ze spousty modulu, spoustou konkurentni komunikace atd. atd. - v Pythonu dostanu obrovsky moloch se spoustou objektu, miliardou zamku a neustale budu resit nejake pady v produkci, protoze nejaky zamek byl napsany spatne. O paralelizovatelnosti a giant locku ani nemluve.
V Erlangu oproti tomu dostanu jasne definovane aktory s jasnym API, _lokalnimi_ stavy a (typicky) asynchronni komunikaci.
Rozdil mezi jednim a druhym se fakt neda merit rychlosti Fib ;)