Maradék szabadidőmben ismét haszontalan dolgokkal kezdtem el foglalkozni, mint pl. a jó öreg Mandelbrot és Julia halmazok. Mivel a Ruby nyelvvel is most ismerkedem, remek alkalomnak tűnt a kettőt kombinálni.
Aztán belefutottam ebbe: http://shootout.alioth.debian.org/u64/performance.php?test=mandelbrot
Azt sejtettem, hogy a Ruby nem a legjobb választás a sima matematikai problémák megoldására - arra továbbra is a legjobb a C vagy a bátrabbaknak az Assembly - de az, hogy ilyen durván lassú legyen, azért nem gondoltam.
A leghosszabb tesztnél egy 16000x16000 pixel méretben kell előállítani az alap Mandelbrot halmazt, színek nélkül, monokróm képként. Ami C-ben 30 másodperc, az Ruby-ban 5400 másodperc, azaz 1 óra 20 perc (Ruby 1.9.2).
A probléma persze nyilvánvaló, Ruby-ban nincsenek primitívek, minden objektum, még a legegyszerűbb szám is.
irb(main):001:0> 2.object_id
=> 5
irb(main):002:0> (1+1).object_id
=> 5
Tehát mindegy hogyan jutunk el '2'-höz, az ugyanaz az objektum lesz, amíg a szám belefér a Fixnum osztályba.
Így a ciklusszervezés, ami szuper primitív kéne hogy legyen, az is brutálisan lassú lesz.
for i in 1..16000 do
for j in 1..16000 do
end
end
Ez a két egymásba ágyazott ciklus ~35 másodpercig tart, ez pont annyi idő ami alatt a C-ben írt algoritmus befejezte a teljes Mandelbrot számítást...
A probléma fokozható:
for i in 2000000001..2000016000 do
for j in 2000000001..2000016000 do
end
end
Ekkor Range-ben már nagyok lesznek az egyes számok, ezek már nem férnek bele a Fixnum class-ba, csak a Bignum class-ba, ekkor valami érdekesség történik az object_id-vel:
irb(main):067:0> 2000000001.object_id
=> 74483390
irb(main):068:0> 2000000001.object_id
=> 74462640
irb(main):069:0> 2000000001.object_id
=> 74458330
Az object_id mindig más és más. Fogalmam sincs mi megy végbe a motorháztető alatt, de bármi is legyen, a gyanúm az volt, hogy nem fogja gyorsítani a futásidőt. Ez be is jött.
A futásidő ebben az esetben már ~150 másodperc lesz, vagyis 5-szörös a Fixnum-hoz képest.
Tehát sajnos az a helyzet, hogy a Ruby teljesen alkalmatlan arra, hogy nagy méretű listák elemeivel akárcsak egyszerű műveleteket is végezzünk, mert a ciklusszervezés önmagában horribilis időveszteséget okoz.
Utolsó kommentek