Tenhle článek jsem si opravdu užil, přestože se Tim Bray hned v úvodu omlouvá za jeho nezáživnost a odhaduje, že na světě může být asi tak šest lidí, které by téma mohlo zajímat. Myslím, že to trochu podcenil. Rozhodně nejsem expert na Ruby (možná leda expert naruby). Článek o efektivitě a optimalizaci parseru XML napsaného pouze v Ruby mě zaujal, protože jsem se před časem zabýval něčím podobným v Perlu. A Perl a Ruby mají, aspoň z hlediska výkonu, dost společného.
Ruby standardně obsahuje parser zvaný REXML. Komu jeho rychlost nestačí, má k dispozici ještě parsery napsané nad céčkovými knihovnami expat a libxml. Tim se pokusil napsat nový parser v Ruby, jako konečný stavový automat (DFA), v podstatě přepsáním svého dávného parseru Lark. Nový parser nazval RX. Dílo se podařilo ale výsledek byl asi desetkrát pomalejší než REXML. Po několika kolech různých optimalizací se podařilo RX urychlit, ale do výkonu REXML mu stále dost chybí.
Zajímavé je, že kromě běžných optimalizací I/O operací pomohlo například rozsekání vstupu regulárními výrazy (místo zpracování po znacích) a odstranění velkého (70 větví) příkazu case. Ukazuje se, že v dynamických jazycích se vyplatí co nejvíc využívat komplexních funkcí jazyka a nesnažit se o vlastní nízkoúrovňové zpracování.
Tim se nevzdal a dál zkoušel a možná ještě zkouší všechno možné, ale v pokračování článku už připustil, že jedinou cestou k rychlému parsování přece jen bude použití expatu nebo libxml, kterému se chtěl na začátku vyhnout. Naprosto stejná je situace v Perlu – pure-Perl parser představuje základní volbu – kdo chce zrychlit, potřebuje expat/libxml.
Další pokračování popisuje pokusy s YARV, virtualním strojem pro Ruby, který by teoreticky mohl mít potenciál oproti interpreteru podstatně urychlit provádění velkého množství jednoduchých operací. K urychlení došlo, ale odstup mezi REXML a RX se skoro nezměnil. RX pravděpodobně doplácí na volbu použít elegantní, ale pro dynamické jazyky málo efektivní algoritmus DFA.
DFA se překládá jako deterministický konečný automat (ta zkratka je tam, jak vidím, i rozvedená), ale tady jde asi o nedopatření. Téma mi připadá zajímavé, jsem Pythonista a výkon interpretovaných jazyků je téma, které se mě hodně dotýká. Padají tam vcelku obecně známé věci (třeba příspěvek A. Pagaltzise), na pochopení některých věcí je třeba rozluštit (brr) kód v Ruby. Doufám, že to za to úsilí stojí.
Zajímavé, že rubistům nedělá problémy pochopit program v Pythonu, zatímco pythonisté se před Ruby třesou… ;-) Kromě toho rubista s rozumem použije na takovýto úkol (jasně definovaný, malá potřeba změny, používají to všichni, protékají tím megabajty dat) spíš Ragel nebo podobný elegantní nástroj, jako to udělal _why s HPricotem. (Use the right tool for the right job, že?)
Tohle je příklad perlovské obfuskace (použité v článku):
@bufs_waiting = buf.scan /<|&|[^<&]+/mu
Vím, že @ označuje typ identifikátoru (atribut instance?), /.*/mu je nějaká práce s regulárními výrazy, m říká, že to je přes více řádek a celý kód, vzhledem ke kontextu, pravděpodobně seká ten kód po začátcích tagů. Znak & by mohl mít podobný význam jako u regulárních výrazů ve Vim. Ale stejně bych musel listovat v nějakém manuálu Ruby, abych to věděl nabeton.
Probůh, jaká obfuskace? @ opravdu znamená instanční proměnnou, ale to je v tuhle chvíli důležité asi jako správný postup přípravy kuřecího frikasé po francouzsku. /…/ je literál regulárního výrazu (setsakra užitečný syntaktický cukr pro Regex.new), za druhým lomítkem mohou být ještě nějaké volby (m = multiline, u = unicode). Jediné, co mi na tomhle přijde ošklivé, je absence závorek ve volání metody. To bohužel Ruby občas umožňuje, já osobně to nepoužívám nikdy.
No on totiz Ruby je IMHO mnohem bohatsi, komplexnejsi a hlavne konzistentnejsi jazyk nez Python (Ruby - vsechno je objekt, pracuje se s metodami modulu/trid/objektu; code blocks/Procs umoznuji vedle expressions i statements; Python - bastl po vzoru jak funkcionalniho, tak objektoveho programovani).
Doporucuji toto srovnani, viz nize. Fakt zajimave, nebot z nej jasne vyplyva, jak si oba jazyky (+ PHP a Perl) stoji co do citelnosti (akorat na zacatku toho Rubu kodu by, myslim, slo nejak pouzit metodu shuffle, ted je to dost neelegantni).
<a href="http://e-scribe.com/news/193">Let’s play a game: BASIC vs. Ruby vs. Python vs. PHP</a>
Za srovnani stoji uplne nejhlavneji tato cast kodu:
[Ruby]
<pre>
puts numbers.join(" ")
</pre>
vs
[Python]
<pre>
print " ".join(map(str, numbers))
</pre>
Nebo i tahle
[Ruby]
<pre>
numbers[0...flipcount] = numbers[0...flipcount].reverse
</pre>
vs
[Python]
<pre>
numbers[:flipcount] = reversed(numbers[:flipcount])
</pre>
@ oznacuje promennou instance, a @@ promennou tridy. I v tomto je videt jasny rozdil mezi obema jazyky co do citelnosti.
S Perlem uz toho Ruby nema moc spolecneho, snad krome "zabudovanych" regularnich vyrazu (ale lze i instancovat patricne tridy, jako v Jave)
IMHO neni nahodou, ze treba Javistum se doporucuje spis Ruby nez Python (viz treba Beyond Java, From Java to Ruby, vzpominam-li si dobre na nazvy techto kniznich titulu).
No a regularni vyrazy by snad mel zvladat kazdy programator, ne?
[8,9] Nemínil jsem, pánové, začínat flame Ruby vs Python. Nejvíce matoucí mi přijde perlovská syntaxe regulárních výrazů a ano, čekal jsem původně, že tam budou větší prasárny - |&| mi z nějakého důvodu připomnělo syntaxi bloků z Ruby.
Argumentace typu "V Ruby je všechno objekt a v Pythonu ne" mi přijde opravdu úsměvná. V Pythonu je všechno objekt a některé objekty lze navíc ještě volat. Pokud někomu přijde syntaxe
@mujAtribut čitelnější než self.mujAtribut a
@@atributTridy čitelnější než MojeTrida.atributTridy,
nemám důvod se s ním hádat, ale já si myslím opak. Že se v knížce From Java To Ruby doporučuje používat Ruby, je skutečně překvapivé. ;-) Mohl bych protiargumentovat Brucem Eckelem, javovským guru, který dává přednost Pythonu, ale jaký to má význam? Já jsem jenom tvrdil, že se mi programy psané v Ruby špatně čtou a že v Pythonu je dobrá čitelnost programu jedním z cílů návrhu. Nic víc jsem netvrdil, na Ruby jsem špínu neházel.
Nechapu, jak nekdo muze chtit hodnotit citelnost perlovskych regexu, kdyz je vlastne nezna.
Ze se v knizce From Java To Ruby doporucuje pouzivat Ruby skutecne prekvapive neni, a normalne ani nikoho nenapadne takto uvazovat, obzvlaste kdyz se radeji zamysli nad faktem, ze kniha s takovym nazvem byla __vubec vydana__. Coz urcite stoji za pozornost, a to vzhledem k faktu, ze jeji vydavatel na jejim vydani velmi pravdepodobne nechtel prodelat (a ze tedy po takovych knihach asi byla/je/bude poptavka, atd.).
Ze je Python __ve srovnani__ s Ruby bastl je zase muj nazor a nevidim na nem zadnou spojitost s hazenim spiny, proboha.
Proti flamu nic nemam, ale prosim priste trochu vic na urovni (napriklad nejakou vecnou "obhajobou" toho mnou uvedeho prvniho code snippetu).
"""Argumentace typu "V Ruby je všechno objekt a v Pythonu ne" mi přijde opravdu úsměvná."""
Sakra, to jsem prece nikde netvrdil! Jde prece o to, ze kdyz "je v pythonu vsechno objekt", tak by v nem nemely kvuli konzistentnosti a prehlednosti byt zadne funkce, ale pouze metody. Jinak to dopadne jako v pripade onoho vyse uvedeneho snipetu.
Přečteno 7 922×
Přečteno 6 030×
Přečteno 6 020×
Přečteno 5 947×
Přečteno 5 814×