Archivi categoria: Dynamic Programming Language

OM il futuro dei framework MVC per Javascript?

In questo articolo viene presentato un interessante confronto tra una applicazione realizzata con backbone.js e la stessa applicazione implementata utilizzando om, una interfaccia in ClojureScript alla libreria React di Facebook.

La cosa originale di questo benchmark è che l’incremento in prestazioni non è dovuto esclusivamente all’utilizzo della libreria React (che ovviamente è utilizzabile anche con altri linguaggi) ma anche al fatto che, essendo le strutture dati di  ClojureScript immutabili, la verifica sul DOM tree effettuata dal metodo shouldComponentUpdate di React avviene in un tempo logaritmicamente inferiore rispetto a quella effettuata esplorando tutto l’albero degli oggetti Javascript come fa backbone.js

Per chi non conoscesse ClojureScript vi posso dire che è un compilatore per il linguaggio Clojure (un dialetto del Lisp) che produce codice Javascript, per approfondimenti potete leggere diversi interessanti articoli su swannodette.github.io

asm.js

Cos’è asm.js?

un nuovo linguaggio di programmazione? no!

un’altra libreria per javascript? no!

un uccello? un aereo? no, niente di tutto questo!

asm.js è un subset del linguaggio javascript utilizzabile da appositi compilatori per produrre applicativi che girano ovunque sia disponibile un interprete javascript, e questi applicativi sono più performanti dei corrispondenti scritti nativamente in javascript !!!

Detto così sembra impossibile, eppure funziona. La magia dipende da due fattori:

il primo è che gli ottimizzatori dei compilatori sono veramente bravi a fare il loro lavoro,

il secondo è che i costrutti di asm.js vengono riconosciuti dagli interpreti javascript ed eseguiti in modo più performante.

Vediamo come funziona: supponiamo di volere eseguire la nostra applicazione scritta in C o in C++, con il compilatore LLVM produciamo del bytecode che viene poi processato dal compilatore emscripten il quale produce codice javascript che viene eseguito nel browser. Il gioco è fatto!

E cosa succede se non lavoriamo con il C o il C++? non importa, date un’occhiata all’elenco di Jeremy Ashkenas dei linguaggi che si compilano in javascript

Per esempio prendiamo un linguaggio a caso …. Ruby, in questa pagina potete divertirvi con l’interprete mruby, compilato dal C al Javascript !

Se siete interessati a qualcosa di meno “serio” date un’occhiata alla demo di BananaBread, uno sparatutto 3D in prima persona che gira nel browser :

 

 

kk

 

 

 

Ruby 2.1: il nuovo Garbage Collector

La versione 2.1 di Ruby introduce un nuovo Garbage Collector, vediamo come funziona!

Come tutti sapete, l’azione del GC è divisa in due fasi:

  1. la fase di Mark, in cui viene esplorato dalla radice l’albero degli oggetti e viene settato il bit FL_MARK per indicare quelli “vivi”
  2. la fase di Sweep, in cui si itera sugli slot dell’heap e gli oggetti con il flag FL_MARK non settato vengono aggiunti alla lista degli oggetti disponibili (per il riutilizzo).

Durante le fasi di Mark e di Sweep, il mondo si ferma e la nostra applicazione Ruby si congela.

Con Ruby 1.8, ad intervalli prestabiliti vengono eseguite in sequenza le due fasi e questo determina un tangibile congelamento dell’applicazione a causa della durata combinata di queste due fasi.

Dalla versione 1.9.3 di Ruby la fase di Sweep anzichè essere eseguita subito dopo quella di Mark, viene suddivisa in microfasi che sono eseguite ogni volta che è richiesta l’allocazione di un nuovo oggetti. In questo modo il tempo necessario a svolgere la fase di Sweep “scompare” dalla nostra percezione, ma rimane quello necessario alla fase di Mark.

Con Ruby 2.0 è stato introdotta la Bitmap Marking GC.
Dietro questo curioso nome si nasconde una intelligente trovata di Narihiro Nakamura: tutti sapete cos’è l’ottimizzazione Copy On Write del sistema di gestione della memoria dei sistemi Linux e Unix based; i processi che vengono forkati (per esempio per gestire più richieste contemporaneamente in un server WEB) mantengono in comune oggetti in memoria fino al momento in cui uno dei processi va ad alterare l’oggetto. Questo consente di minimizzare l’utilizzo di memoria, ma nel momento in cui la fase di Mark altera il bit FL_MARK, questo fa  venire meno la suddetta condizione e quindi l’ottimizzazione COW fallisce (limitatamente agli oggetti allocati dalla nostra applicazione Ruby). L’idea di Narihiro Nakamura è quella di spostare il bit FL_MARK in una sottostruttura (una bitmap) che diventa la sola parte che viene “sporcata” nella fase di Mark.

In Ruby 2.1 è stato introdotto un nuovo GC: questo è chiamato RGENGC (Restricted Generational GC), un GC generazionale parte dal presupposto che la maggior parte degli oggetti vengono allocati e poi “muoiono giovani”, il GC distingue tra oggetti “giovani” ed oggetti “vecchi”: gli oggetti “vecchi” sono quelli che “sopravvivono” all’n-esimo GC.

Con l’RGENGC vengono effettuati due distinti GC, il Minor GC in cui vengono trattati gli oggetti “giovani” e il Major GC (che viene eseguito solo quando la memoria scarseggia) in cui vengono trattati entrambi.

(segue)

 

 

 

KiloHertz, MegaHertz, GigaHertz, …. #2

Nella prima parte abbiamo stabilito che ogni singola istruzione eseguita dal microprocessore è suddivisa in stati.

In base al tipo di microprocessore varia il numero di stati associati ad ogni istruzione, consideriamo per esempio l’istruzione NOP (no operation):

ebbene si, esiste un comando per dire al microprocessore di non fare nulla, ma di questo parleremo un’altra volta….

Confronteremo il numero di cicli di clock necessari per eseguire il comando NOP su 3 microprocessori a 8 bit preistorici (cioè di quando ero giovane).

INTEL8080 il primo processore a 8 bit di INTEL 4 cicli
MOS Technology 6502 utilizzato da APPLE per il suo APPLE IIe 2 cicli
ZILOG Z80 il cui successo è legato alla diffusione del s.o. CP/M 4 cicli

Già da questo esempio notiamo differenze abbastanza rilevanti, inoltre il 6502 implementa un meccanismo di pipeline per cui mentre esegue l’istruzione NOP nel secondo ciclo di clock, sta già leggendo l’istruzione successiva.

L’affare si complica!

(segue)

What’s a Symbol?

In Ruby esistono due modi per definire un dato di tipo testuale:

il primo utilizza la classe String, il secondo utilizza la classe Symbol:

a = "lettera_a"
b = :lettera_b

utilizzando il metodo class possiamo verificare che a è un oggetto di classe String invece b è un oggetto di classe Symbol.

se creiamo altri due oggetti con le stesse espressioni letterali possiamo notare una cosa:

a2 = "lettera_a"
b2 = :lettera_b
a.object_id == a2.object_id       # false
b.object_id == b2.object_id       # true

le stringhe a ed a2, nonostante abbiano lo stesso contenuto, sono oggetti diversi!

invece i simboli b e b2 sono in realtà lo stesso simbolo.

Ora se creo un simbolo b3 convertendo una stringa con il contenuto “lettera_b” anche questo sarà una ulteriore istanza del simbolo :lettera_b

b3 = "lettera_b".to_sym
b3.object_id == b2.object_id         # true

Quanto osservato ha due implicazioni: la prima è che utilizzando i simboli al posto delle stringhe utilizziamo meno memoria, la seconda, più rilevante, è che dovendo confrontare due simboli l’interprete Ruby si limita a confrontare gli object_id, operazione ben più veloce di un confronto carattere per carattere.

 

 

RoR 4.1.0 beta 1 released!

ror

E’ Natale e il regalo di quest’anno è l’anteprima di Ruby On Rails 4.1

Spring Application Preloader

Spring velocizza lo sviluppo mantenendo l’applicazione in esecuzione in background,  evitando di riavviarla ogni volta che dovete eseguire un task di rake, una migrazione oppure un test.

config/secrets.yml

Questo files, che di default memorizza il parametro secret_key_base dell’applicazione, può essere utilizzato anche per memorizzare le chiavi di accesso per altre API externe.

Per esempio possiamo mantenere l’access key dei web services amazon

development:
  secret_key_base: 3b7cd727ee24e8444053437c36cc66c3
    aws_access_key: 09876543212345678
ed accedervi quando necessario nell’applicazione
aws_acc_key = Rails.application.secrets.aws_access_key

Action Pack Variants

I request variant  sono una specializzazione dei request format
che consentono di effettuare render differenziati in base al dispositivo da cui avviene la richiesta:

respond_to do |format|
    format.js      { ...... }
    format.desktop    { ....... }
    format.phone  { ....... }
    format.tablet   { ....... }
end

il variant deve essere impostato in una before_action

request.variant = :tablet if request.user_agent =~ /iPad/

Action Mailer Previews

Visitando uno speciale url è possibile visualizzare in anteprima l’aspetto delle email prodotto dall’Action Mailer.

Active Record Enums

Ora è possibile associare dei nomi ai valori numerici di un campo intero di una tabella.
Class Invoice < ActiveRecord::Base
        enum status: [ :suspended, :active, :payed ]
end

if status.payed? ......
………….. prosegue nel prossimo articolo …………..