Domanda

Devo serializzare un'enorme quantità di dati (circa 2 GB) di piccoli oggetti in un singolo file per poter essere successivamente elaborato da un altro processo Java. Le prestazioni sono piuttosto importanti. Qualcuno può suggerire un buon metodo per raggiungere questo obiettivo?

È stato utile?

Soluzione

Hai dato un'occhiata ai buffer di protocollo di Google ? Sembra un caso d'uso per questo.

Altri suggerimenti

Non so perché la serializzazione Java sia stata scartata, è un meccanismo perfettamente praticabile.

Non è chiaro dal post originale, ma tutti i 2G di dati sono nell'heap contemporaneamente? O stai scaricando qualcos'altro?

Fuori dalla scatola, la serializzazione non è la "quot" perfetta " soluzione, ma se implementi Externalizable sui tuoi oggetti, la serializzazione può funzionare bene. La grande spesa delle serializzazioni è capire cosa scrivere e come scriverlo. Con l'implementazione di Externalizable, prendi quelle decisioni dalle sue mani, ottenendo così un notevole aumento delle prestazioni e un risparmio di spazio.

Sebbene l'I / O sia un costo primario per la scrittura di grandi quantità di dati, i costi accidentali della conversione dei dati possono anche essere molto costosi. Ad esempio, non vuoi convertire tutti i tuoi numeri in testo e poi di nuovo, meglio se possibile memorizzarli in un formato più nativo. ObjectStream ha metodi per leggere / scrivere i tipi nativi in ??Java.

Se tutti i tuoi dati sono progettati per essere caricati in una singola struttura, potresti semplicemente fare ObjectOutputStream.writeObject (yourBigDatastructure), dopo aver implementato Externalizable.

Tuttavia, puoi anche scorrere la tua struttura e chiamare writeObject sui singoli oggetti.

Ad ogni modo, avrai bisogno di alcuni " objectToFile " di routine, forse diversi. Ed è proprio quello che offre Externalizable, oltre a un framework per seguire la tua struttura.

L'altro problema, ovviamente, è il controllo delle versioni, ecc. Ma poiché implementate voi stessi tutte le routine di serializzazione, avete anche il pieno controllo su di esse.

Un approccio più semplice che mi viene subito in mente è l'utilizzo del buffer NIO (java.nio.MappedByteBuffer) associato alla memoria. Utilizzare il singolo buffer (approssimativamente) corrispondente alla dimensione di un oggetto e scaricarli / aggiungerli al file di output quando necessario. I buffer mappati in memoria sono molto efficienti.

Hai provato la serializzazione Java? Li scriveresti usando un ObjectOutputStream e rileggili utilizzando un ObjectInputStream . Naturalmente le classi dovrebbero essere Serializable . Sarebbe la soluzione a basso sforzo e, poiché gli oggetti sono archiviati in binario, sarebbe compatto e veloce.

Se le prestazioni sono molto importanti, è necessario scriverle da sé. È necessario utilizzare un formato binario compatto. Perché con 2 GB le operazioni di I / O su disco sono molto importanti. Se usi un formato leggibile come XML o altri script ridimensiona i dati con un fattore di 2 o più.

A seconda dei dati può essere accelerato se si comprimono i dati al volo con un basso tasso di compressione.

Una totale no go è la serializzazione Java perché, leggendo Java, controlla ogni oggetto se è un riferimento a un oggetto esistente.

Ho sviluppato JOSIP come alternativa al database.

Apache Avro potrebbe anche essere utile. È progettato per essere indipendente dalla lingua e ha collegamenti per le lingue popolari .

Dai un'occhiata.

buffer di protocollo: ha senso. ecco un estratto dal loro wiki: http://code.google.com/apis /protocolbuffers/docs/javatutorial.html

Ottenere più velocità

Per impostazione predefinita, il compilatore del buffer di protocollo tenta di generare file più piccoli utilizzando reflection per implementare la maggior parte delle funzionalità (ad esempio analisi e serializzazione). Tuttavia, il compilatore può anche generare codice ottimizzato esplicitamente per i tipi di messaggi, fornendo spesso un aumento delle prestazioni di un ordine di grandezza, ma anche raddoppiando le dimensioni del codice. Se la profilazione mostra che l'applicazione sta impiegando molto tempo nella libreria del buffer di protocollo, dovresti provare a cambiare la modalità di ottimizzazione. Aggiungi semplicemente la seguente riga al tuo file .proto:

opzione optim_for = SPEED;

Riesegui il compilatore del protocollo e genererà analisi, serializzazione e altro codice estremamente veloci.

Probabilmente dovresti considerare una soluzione di database: tutto ciò che i database fanno è ottimizzare le loro informazioni, e se usi Hibernate, mantieni il tuo modello di oggetto così com'è e non pensi nemmeno al tuo DB (credo sia per questo che si chiama ibernazione, archivia i tuoi dati e poi riportali indietro

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top