Ho un programma Java che prepara i dati in una struttura di dati piuttosto complessa e grande in memoria (diversi GB) e li serializza su disco, e un altro programma che legge in memoria la struttura di dati serializzata. Sono stato sorpreso di notare che il passo di deserializzazione è piuttosto lento e che è legato alla CPU. (100% di utilizzo della CPU in top
ma solo da 3 a 5 MB/s letti con iotop
, che è molto basso per quelle che dovrebbero essere le letture sequenziali su un disco rigido). La CPU è abbastanza recente (Core i7-3820), la struttura si adatta alla memoria, nessuno spazio di swap è configurato.Perché la deserializzazione di Java è legata alla CPU?
Perché è così? Esiste un modo alternativo per serializzare oggetti in Java che non ha la CPU come collo di bottiglia?
Ecco il codice di deserializzazione, nel caso in cui è importante:
FileInputStream f = new FileInputStream(path);
ObjectInputStream of = new ObjectInputStream(f);
Object obj = of.readObject();
IIRC utilizza magico riflesso paragonabile al modo in cui il lavoro .NET serializzatori. È lento. Esiste un concetto concettualmente semplice, ma "molto digitato", per evitare tutto questo: fallo a mano. Cioè, scrivere oggetti ricorsivamente, campo per campo, su un flusso binario. E il contrario per il caricamento. – harold
Questo potrebbe aiutare: http://vanillajava.blogspot.co.uk/2011/10/serialization-using-bytebuffer-and.html – assylias
Puoi provare a completare il wrapping di FileInputStream con un BufferedInputStream? –