Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Ruby: quale Virtual Machine?

Un confronto tra i diversi interpreti e le diverse tecnologie
Un confronto tra i diversi interpreti e le diverse tecnologie
Link copiato negli appunti

Dalla nascita di Rails ai giorni nostri sono emerse moltissime realtà che hanno fatto di questo framework (e quindi di Ruby) il loro portabandiera, basti pensare a siti come Twitter, Yellowpages e lo stesso Basecamp. Tutte queste applicazioni hanno però messo in evidenza un altro aspetto di questa tecnologia: le scarse performance della Virtual Machine.

Per ovviare a questo problema, sono venuti alla luce diversi progetti di Virtual Machines alternative, con l'obiettivo di migliorare quella esistente. In questo articolo mettiamo a confronto le diverse alternative specificando per ognuna di esse: lo stato di avanzamento, il livello di compatibilità con la VM originale, i pregi ed i difetti.

MRI: Matsumoto Ruby Interpreter

Sotto questo acronimo si nasconde la Virtual Machine originale, sviluppata ed evoluta da Matz fin dal 1993. A tutt'oggi la maggior parte delle applicazioni (Web o meno) scritte in Ruby sono eseguite su questa Virtual Machine. Inoltre è la macchina virtuale per la quale sono sono disponibili il maggior numero di gems.

Come accennato, la MRI è tristemente nota per le scarse performance, dovute ad una moltitudine di fattori, tra i quali spicca l'assenza di uno step intermedio tra la lettura e l'esecuzione del codice.

Questa VM non genera alcun tipo di bytecode, ma memorizza le informazioni in una struttura chiamata Abstract Syntax Tree che, se da un lato ben si presta alle potenzialità di metaprogrammazione di Ruby, dall'altro riduce drasticamente le prestazioni obbligando il programma ad effettuare ricerche, a volte anche complesse, soltanto per recuperare il valore di una variabile.

Altro aspetto che lascia perplessi è la sua incapacità nel gestire Threads a livello del sistema operativo. La MRI infatti utilizza green threads, cioè thread che risiedono all'interno della VM risultando in questo modo completamente invisibili al sistema operativo. Questa scelta implementativa da un lato garantisce la piena portabilità della MRI su diversi SO, dall'altro implica un notevole prestazionale, soprattutto nel caso in cui la macchina sulla quale si stia eseguendo l'applicazione sia multi-core o multi-processore (in questi casi infatti threads normali possono essere eseguiti contemporaneamente su core diversi, green threads no).

Tra gli aspetti positivi vanno invece annoverate le migliaia di gems nativamente sviluppate su questo interprete, cosi come, nel caso si volesse utilizzare Rails, la disponibilità di svariate architetture di produzione costruite su questa Virtual Machine.

Alla data di stesura di questo articolo MRI è disponibile nella versione 1.8.7 che si configura principalmente come una release-ponte tra la 1.8.6 e la 1.9.0 che però utilizzerà una nuova Virtual Machine.

Ruby 1.9 - YARV

All'Euruko 2008 di Praga, Sasada Koichi ha tenuto una sessione sull'interprete Ruby da lui sviluppato e battezzato YARV: Yet Another Ruby Virtual Machine. I benchmarks mostrati furono talmente positivi da caratterizzare su alcune specifiche funzioni aumenti della velocità di esecuzione del 180% rispetto alla Virtual Machine di Matzumoto.

In effetti, già dalla fine del 2007, YARV faceva parte parte del core dell'interpete per Ruby 1.9.0.

A differenza dell'MRI questo interprete lavora producendo un bytecode del file sorgente ed interpretandolo; questa tecnica, unita a decine di altri accorgimenti, rende YARV molto più performante del suo predecessore. A titolo di esempio ecco alcuni benchmarks fatti da Antonio Cangiano il 28 Novembre 2007 su di un piccolo programma ricorsivo per il calcolo dei primi n valori della serie di Fibonacci:

Esempio di output su console

Ruby   1.8.6:   158.869s
Python 2.5.1:   31.507s
Ruby   1.9.0:   11.934s

Altra nota positiva è la futura implementazione dei Thread nativi; al momento questa feature è considerata come sperimentale ma dovrebbe diventare realtà nel prossimo Ruby 2.0.

Passiamo ora ai lati negativi: in primis Ruby 1.9 non è considerata una release stabile, ma utilizzabile solo a fini di sviluppo e test, questo purtroppo pregiudica il suo utilizzo in ambiente di produzione anche se Koichi Sasada ha annunciato per dicembre 2008 Ruby 1.9.1 che dovrebbe invece poter essere utilizzata anche per tale scopo.

Altra nota da considerare: Ruby 1.9 è intrinsecamente non retrocompatibile al 100% con Ruby 1.8.6, questo implica che buona parte delle librerie ad oggi disponibili per MRI debbano essere riscritte per poter essere utilizzate con il nuovo interprete, il processo di refactoring è già cominciato ma ci vorrà del tempo prima di poter apprezzare la stessa varietà di gems diponibili oggi per Ruby 1.8.6.

Per quanto riguarda invece chi sviluppa utilizzando Ruby on Rails le notizie sono più rosee, Rails è infatti compatibile con Ruby 1.9 sin dalla versione 2.0.2 e può quindi essere utilizzato all'interno di questo nuovo interprete beneficiando di un'incremento prestazionale vicino al 15%; chiaramente lo stesso discorso non può essere esteso a tutti i plugins in circolazione ma soltanto a quelli che sono stati gia convertiti e/o testati su Ruby 1.9.

JRuby

JRuby è un'implementazione del linguaggio Ruby in Java; il che significa che l'interprete è eseguito all'interno della JVM. Questo progetto nasce nel 2001 da un'idea di Jan Arne Petersen al quale, nel corso degli anni, si affiancano altri sviluppatori entusiasti; tra questi Charles Nutter e Thomas Enebo che nel 2006 vengono assunti dalla Sun Microsystems per lavorare a tempo pieno a questo interprete.

Molti sono i vantaggi di questo interprete; primo fra tutti il fatto che alla base del codice eseguito risieda la Java Virtual Machine, sinonimo di stabilità e robustezza nel mondo enterprise. Inoltre JRuby mappa automaticamente le librerie Java in Ruby consentendo di utilizzare immense quantità di codice scritto per questo linguaggio nel corso degli anni, ecco un esempio di interazione con le librerie javax.swing:

require 'java'

frame = javax.swing.JFrame.new("Window") 
label = javax.swing.JLabel.new("Hello")
frame.getContentPane.add(label) 
frame.setDefaultCloseOperation(javax.swing.JFrame::EXIT_ON_CLOSE)
frame.pack
frame.setVisible(true)

Un altro vantaggio, sempre legato alla posizione di Java nel mondo business, è la possibilità di avvalersi di ambienti di produzione altamente sofisticati e molto ben collaudati.

Passiamo alle note negative: JRuby è, dal punto di vista della gestione della memoria, più esigente rispetto ad altri interpreti e il fatto che sia legato alla JVM lo rende più lento anche in fase di start-up dell'applicazione.

A livello di prestazioni invece JRuby, utilizzato in modalità Just-in-time compiler, registra valori di benchmark vicini a quelli di Ruby 1.9.0.

Ad oggi JRuby è disponibile nella versione 1.1.4 ed è compatibile quasi al 100% con il linguaggio Ruby 1.8.6. Per quanto riguarda lo sviluppo Web possiamo tirare un sospiro di sollievo, Ruby on Rails è supportato da questo interprete senza particolari problemi e per gli sviluppatori che intendono avvalersi di JRuby c'è anche la possibilità di utilizzare il famoso (e performante) application server della sun: GlassFish.

Rubinius

Rubinius nasce dall'idea di Evan Phoenix secondo la quale se Ruby è un'ottimo linguaggio allora l'interprete di Ruby deve necessariamente essere scritto in Ruby. L'obiettivo di Rubinius è infatti quello di utilizzare il C solo per definire alcune funzioni primitive e su queste costruire tutto set di core classes direttamente in linguaggio Ruby.

Rubinius è al momento compatibile con la versione 1.8.6 del linguaggio e supporta Rails, tra i suoi punti di forza devono essere segnalati l'assoluta eleganza con la quale è stato sviluppato, cercando di utilizzare funzioni in C solo laddove fosse strettamente necessario. Rubinius inoltre vanta un Garbage Collector più efficiente rispetto a quello dell'MRI e dei benchmarks di tutto rispetto che lo posizionano decisamente più in alto rispetto all'interprete tradizionale (grazie anche al fatto che, come per YARV, anche qui l'interprete produce bytecode).

Il principale lato negativo di questo interprete è da ricercarsi nella sua giovinezza. Rubinius supporta Rails solo da Maggio 2008 e tuttora la compatibilità con il linguaggio 1.8.6 non è certificata al 100%. Inutile dire che questo incide pesantemente anche sulla sua affidabilità rendendolo al momento un interprete utile solo a fini di sviluppo.

MacRuby

MacRuby è una versione di Ruby 1.9 che ha subito una procedura di refactoring per poter lavorare nativamente con le tecnologie ed i framework classici del Mac come l'Objective-C e il CoreFoundation framework. A differenza di tutti gli interpreti fin qui presentati MacRuby non ambisce alla compatibilità con tutti i sistemi operativi, né annovera tra le sue finalità l'operatività di Ruby on Rails; il vero obiettivo di questo interprete è invece quello di garantire agli sviluppatori la possibilità di creare applicazioni GUI-enabled per Mac beneficiando dell'eleganza del linguaggio Ruby.

A titolo di esempio ecco un listato di codice Objective-C che crea un'istanza dell'oggetto Person ed esegue su di esso alcune operazioni di tipo get/set:

Person *person = [Person new]; 
[person name];                                
[person setName:name];                         
[person setFirstName:first lastName:last]; 

Ed ora lo stesso codice utilizzando MacRuby:

person = Person.new
person.name
person.setName name 
person.setFirstName first, :lastName => last

Al momento questo interprete è disponibile solo per ambienti di sviluppo in quanto l'attuale versione, la 0.3, si configura più come beta che come release stabile.

Progetti "minori"

Per completare questa veloce e non esaustiva panoramica degli interpreti ad oggi disponibili per Ruby vorrei citare alcuni altri prodotti che non si sono aggiudicati uno spazio più grande a causa della loro giovinezza, delle poche informazioni disponibili o della poca conoscenza in merito da parte di chi scrive.

IronRuby

IronRuby sta al mondo .NET come JRuby sta a Java: questo interprete infatti è stato scritto utilizzando il DLR: Dynamic Language Runtime della Microsoft. Al momento IronRuby non è perfettamente compatibile con Ruby 1.8.6 e questo gli impedisce di supportare completamente Ruby on Rails (anche se è gia stato dimostrato che alcune porzioni di questo framework possono essere utilizzate con questo interprete) ma gli sforzi profusi in tal senso sono notevoli.

MagLev

È un'implementazione Ruby 1.8.6 costruita per favorirne la scalabilità, si basa su tecnologia SmallTalk ed implementa una Virtual Machine strutturata come quella di Rubinius. Al momento non esiste una versione disponibile al pubblico di questo interprete, che però dovrebbe essere rilasciato a breve.

XRuby

XRuby si differenzia rispetto a tutte le implementazioni fino a qui presentate in quanto non opera come un interprete ma come un compilatore: per la precisione un compilatore Ruby to Java capace di tradurre file scritti in linguaggio Ruby in bytecode java (i classici file .class).

HotRuby

Come gli stessi autori citano nell'homepage del sito «HotRuby runs Ruby source code on a Web browser and Flash». Seppure HotRuby sia in fase iniziale e pochissime funzionalità del linguaggio Ruby siano state implementate, il progetto di per se, cercando di portare questo linguaggio nel mondo client-side, potrebbe a lungo termine rivelarsi interessante.

Ti consigliamo anche