2013-08-10 12 views
14

Se ho un grafo di oggetti nidificati di classi case, simile all'esempio seguente, e voglio memorizzarle in un elenco redis, quali librerie o strumenti dovrei guardare a quello che darà il più veloce viaggio di andata e ritorno ai redis?Serializzazione/deserializzazione più veloce delle classi di casi Scala

Ciò includerà:

  • Tempo per serializzare l'oggetto
  • costo rete di trasferimento dei dati serializzati
  • costi di rete di recupero dei dati memorizzati serializzati
  • tempo per deserializzare nuovo in classi case

    case class Person(name: String, age: Int, children: List[Person]) {} 
    

risposta

25

AGGIORNAMENTO (2018): scala/decapaggio non viene più mantenuto attivamente. Ci sono orde di altre biblioteche che sono sorte come alternative che adottano approcci simili ma che tendono a concentrarsi su formati di serializzazione specifici; ad esempio, JSON, binary, protobuf.

vostro caso d'uso è esattamente il caso d'uso mirato per Scala/decapaggio (https://github.com/scala/pickling). Disclaimer: Sono un autore.

Scala/pickling è stato progettato per essere un'alternativa più veloce, più tipicamente e più aperta ai framework automatici come Java o Kryo. È stato progettato in particolare per le applicazioni distribuite, pertanto i tempi di serializzazione/deserializzazione e le dimensioni dei dati serializzati occupano un posto in prima fila. Ci vuole un approccio diverso alla serializzazione tutti insieme: genera il codice di pickling (serializzazione) in linea al sito di utilizzo in fase di compilazione, quindi è davvero molto veloce.

Gli ultimi benchmark sono nel nostro OOPSLA paper - per il formato di pickle binario (puoi anche scegliere altri, come JSON) scala/pickling è sempre più veloce di Java e Kryo e produce rappresentazioni binarie che sono alla pari o inferiori a quelle di Kryo , significa meno latenza quando si passano i dati sottoposti a pickup in rete.

Per maggiori informazioni, c'è una pagina del progetto: http://lampwww.epfl.ch/~hmiller/pickling

E un ScalaDays 2013 talk from June on Parley's.

Presenteremo anche alcuni nuovi sviluppi, in particolare relativi alla gestione dell'invio delle chiusure attraverso la rete a Strange Loop 2013, nel caso in cui ciò potrebbe essere un punto dolente per il vostro caso d'uso.

Al momento della stesura di questo articolo, scala/pickling è in pre-rilascio, con la prima versione stabile prevista per il 21 agosto.

+0

Questo sembra abbastanza utile, ma la GitHub la pagina è un po 'corta. Darò sicuramente un'occhiata a quegli sguardi e grazie per la risposta. – user2668128

+0

* collegamenti. Btw, JSON è il miglior formato per le prestazioni, o era solo l'esempio su github? – user2668128

+1

Sì, stiamo lavorando alla documentazione. Ci saranno altre informazioni sulle istruzioni d'uso nella prossima settimana o due insieme alla versione. Il nostro formato binario è il nostro formato più sintonizzato sulle prestazioni. Anche se JSON dovrebbe essere abbastanza veloce (non abbiamo ancora pubblicato benchmark completi per JSON). –

6

Aggiornamento:

È necessario fare attenzione ad utilizzare i metodi serialize da JDK. Le prestazioni non sono eccezionali e un piccolo cambiamento nella tua classe renderà i dati impossibili da deserializzare.


Ho usato scala/pickling ma ha un blocco globale durante la serializzazione/deserializzazione.

Così, invece di usarlo, scrivo il mio codice di serializzazione/deserializzazione come questo:

import java.io._ 

object Serializer { 

    def serialize[T <: Serializable](obj: T): Array[Byte] = { 
    val byteOut = new ByteArrayOutputStream() 
    val objOut = new ObjectOutputStream(byteOut) 
    objOut.writeObject(obj) 
    objOut.close() 
    byteOut.close() 
    byteOut.toByteArray 
    } 

    def deserialize[T <: Serializable](bytes: Array[Byte]): T = { 
    val byteIn = new ByteArrayInputStream(bytes) 
    val objIn = new ObjectInputStream(byteIn) 
    val obj = objIn.readObject().asInstanceOf[T] 
    byteIn.close() 
    objIn.close() 
    obj 
    } 
} 

Ecco un esempio di utilizzo:

case class Example(a: String, b: String) 

val obj = Example("a", "b") 
val bytes = Serializer.serialize(obj) 
val obj2 = Serializer.deserialize[Example](bytes) 
Problemi correlati