Sembra essere nata sotto una cattiva stella la macchina virtuale posta alla base della piattaforma Android, sviluppata dall’omonima azienda, poi acquisita dalla ben più famosa Google.
Che non brilli per velocità è un fatto abbastanza noto agli addetti ai lavori, ma percepibile anche dalla normale utenza, che trova soddisfazioni su configurazioni hardware più elevate rispetto al vasto parco hardware sul quale gira.
D’altra parte Dalvik non è stata concepita per essere votata alle prestazioni, quanto piuttosto all’efficienza in termini di memoria utilizzata, grazie ad alcuni intelligenti accorgimenti (tutti i file binari generati a partire dal sorgente vengono accorpamenti in un unico eseguibile, mentre le costanti comuni a tutti i file sono “raggruppate” in modo da essere presenti una sola volta in memoria).
Infatti inizialmente, come capita quando si realizza una virtual machine (VM d’ora in poi), il progetto verteva esclusivamente sull’interpretazione, bytecode dopo bytecode, del codice dell’applicazione, con tempi d’esecuzione decisamente bassi rispetto a soluzioni similari, ma che supportavano già la cosiddetta compilazione JIT (Just-In-Time) nel codice macchina dell’architettura ospite.
In realtà Dalvik strizzava l’occhio anche alla velocità, in quanto il progettista ha pensato bene di scegliere di implementarla come VM basata sui registi anziché sullo stack, consentendo al contempo di compattare ancora meglio il codice (occupando, quindi, meno spazio).
Queste due filosofie sono da sempre contrapposte, ed è ancora oggetto di discussione quale delle due sia migliore dal punto di vista puramente prestazionale, anche se personalmente propendo per la prima (avendo anche potuto toccare con mano i risultati col mio progetto WPython).
Anche se Android è un progetto del 2003, la prima versione è stata commercializzata soltanto nel 2008 con la VM esclusivamente interpretata, mentre bisogna aspettare il 2010 per poter avere una versione di Dalvik che fa finalmente uso di un compilatore JIT, portando a un miglioramento delle prestazioni che in alcuni casi arriva quasi al 500%.
Nonostante i buoni propositi, i risultati sono ancora distanti dalla concorrenza (per non parlare poi dello stato dell’arte rappresentato dalla JDK in versione server), come provano alcuni benchmark pubblicati da Oracle un po’ di mesi dopo il rilascio di Android 2.2.
Nello specifico, è stata testata la versione “Embedded” della Java VM 1.6 della casa madre, anche se a completamento dei test sarebbe stato auspicabile veder pubblicata anche l’occupazione di memoria, visto che parliamo di dispositivi mobile (che non ne mettono a disposizione una quantità elevata), e il tempo di avvio (non si può attendere troppo tempo per far partire un’applicazione).
Di recente è apparso un progetto che ha fatto decisamente scalpore, poiché si tratta di una riscrittura di Android in C#, facendo uso di appositi strumenti che si occupano del grosso del lavoro, analizzando i file Java e convertendoli nell’equivalente in C#, a cui si è aggiunto un po’ di lavoro manuale per sistemare alcune parti.
Si tratta di XobotOS, nato da un’idea del team di Xamarin, azienda fondata da Miguel de Icaza, che si occupa del ben noto progetto Mono, alternativa open source al più famoso framework .NET.
I risultati hanno dell’incredibile: Dalvik viene letteralmente stracciata nei test che sono stati utilizzati (e messi a disposizione per chi volesse riprodurli), con XobotOS che va ben oltre le 2-3 volte più veloce del precedente con la JVM 1.6 embedded, arrivando a toccare anche le 10 volte.
Anche Mono, come la JVM, fa uso di una VM basata sullo stack, al contrario di Dalvik che è basata sui registri, ma con un compilatore JIT questo dettaglio non è molto importante, a meno che non viene dimostrato che è proprio la struttura di quest’ultima VM a porre un freno alla bontà del JIT e del codice che da esso viene generato.
Alla luce di questi risultati credo sia importante per Google ripensare pesantemente Dalvik perché, nonostante tutto il tempo che è passato, questa VM non si dimostra ancora competitiva con quanto offerto dalla concorrenza.
Sun, com’è noto, ha parecchia esperienza in questo campo, con tutto il lavoro svolto su quella di Java. Ma Xamarin? Mono è un progetto relativamente giovane, iniziato nel 2001 e la cui prima versione è stata rilasciata nel 2004. Android è un progetto iniziato nel 2003, e la cui prima versione (commerciale) è stata rilasciata nel 2008.
E’ difficile credere che Google non possa mettere a disposizione sufficienti risorse per migliorare lo stato della VM di Android, se consideriamo gli sforzi profusi in quella Javascript per il suo browser, ma soprattutto il fatto che Mono è stato portato avanti da una piccola squadra di sviluppatori.
Sarà necessario rimboccarsi le maniche, andando prima a confrontare le implementazioni della JVM e di Mono, cogliere le differenze di rilievo (quelle che incidono sulle prestazioni) rispetto a Dalvik, e cercare di aggiornare e migliorare quest’ultima in modo da rendersi finalmente competitiva.
Si potrebbe anche pensare di prendere a piene mani dalla JVM, o magari di prelevarla in blocco e adattarla a Dalvik, ma visti i recenti trascorsi con Oracle, non credo che Google abbia voglia di trovarsi con un altro contenzioso legale.
Passare a Mono / XobotOS è da escludere del tutto: troppa diversa la piattaforma, che mal si concilia con l’enorme parco software già sviluppato per Android, che non si può certo ricompilare.
Tra l’altro non è ancora chiaro il futuro di XobotOS. Nel blog si parla di mettere a disposizione degli sviluppatori Android questa nuova piattaforma, ma non è pensabile che si possa sostituire completamente la già esistente VM. Al più XobotOS potrebbe girare come applicazione “nativa”, sfruttando l’NDK di Android per avviarsi, per poi rendersi completamente indipendente da Dalvik, ma appare una complicazione inutile visto che esiste già MonoDroid.
Se il limite dovesse rivelarsi proprio la struttura di Dalvik, si potrebbe anche realizzare una nuova VM pensata appositamente per offrire prestazioni migliori. Il problema rimarrebbe il parco software installato, ma una buona soluzione di compromesso potrebbe essere quella di convertire al volo il pacchetto .dex nel nuovo formato, ed eseguire quest’ultimo.
D’altra parte è ciò che avviene già quando si genera il file .dex, che contiene tutto il codice dell’applicazione Android. Si parte dai normalissimi file Java che vengono prodotti dalla compilazione dei sorgenti, che vengono poi accorpati e il cui bytecode Java convertito infine in quello specifico di Dalvik.
In questo modo le nuove applicazioni potrebbero sfruttare al meglio la nuova VM, generando codice appositamente ottimizzato, mentre quelle vecchie potrebbero continuare a girare senza problemi tramite la già citata operazione di conversione (trasparente all’applicazione stessa).
E’ bene tenere presente anche un’altra cosa: la poca memoria a disposizione dei dispositivi mobile non è più un problema che possa fungere da deterrente nell’impiego di nuove soluzioni che potrebbero essere più esigenti da questo punto di vista. Sono motivazioni che potevano andare bene un po’ di anni fa, ma certamente non oggi, dove alcuni smartphone hanno addirittura 1GB di memoria centrale, e… l’asticella che continua ad alzarsi.
Si tratta, in ogni caso, di idee che vengono fuori dall’esperienza accumulata in questo settore, ma che potrebbero non essere applicabili allo specifico contesto, per cui sono da prendere sempre con le pinze.