Sto cercando un modo per deserializzare uno String
da un byte[]
in Java con il minor numero di rifiuti possibile. Poiché sto creando il mio serializzatore e il de-serializzatore, ho la completa libertà di implementare qualsiasi soluzione sul lato server (ad esempio durante la serializzazione dei dati) e sul lato client (ad esempio, quando la serializzazione dei dati).Deserializzazione Zero-Garbage String in Java, problema oggetto Humongous
sono riuscito efficientemente serializzare un String
senza incorrere in alcun overhead immondizia scorrendo le String's
caratteri (String.charAt(i)
) e convertendo ogni char
(valore a 16-bit) a 2x valore a 8 bit. C'è un bel dibattito su questo here. Un'alternativa è utilizzare Reflection per accedere direttamente allo char[]
, ma questo non rientra nell'ambito del problema.
Tuttavia, sembra impossibile per me deserializzare il byte[]
senza creare il char[]
due volte, che sembra, beh, strano.
La procedura:
- Creare
char[]
- Scorrere
byte[]
e compilare ilchar[]
- Crea String con
String(char[])
costruttore
A causa di String
regole immutabilità di Java, il costruttore copia il carattere [], creando 2x overhead GC. Posso sempre usare i meccanismi per eludere questo (allocazione non sicura String
+ Reflection per impostare l'istanza char[]
), ma volevo solo chiedere se ci sono delle conseguenze su questo diverso da me che infrange ogni convenzione sull'immutabilità String's
.
Naturalmente, la risposta più saggia a questo sarebbe "dai, smetti di fare questo e abbi fiducia in GC, l'originale char[]
sarà estremamente breve e G1 se ne libererà momentaneamente", che in realtà ha senso , se lo char[]
è inferiore a 1/2 della dimensione della regione del G1. Se è più grande, il carattere [] verrà assegnato direttamente come oggetto gigantesco (cioè propagato automaticamente al di fuori della regione del G1). Tali oggetti sono estremamente difficili da raccogliere in modo efficiente in G1. Ecco perché ogni assegnazione è importante.
Qualche idea su come affrontare il problema?
Molte grazie.
hai semplicemente considerato di non lavorare con le stringhe e solo serializzare i dati di byte grezzi e fare conversioni di set di caratteri nelle sottosezioni quando è assolutamente necessario? – the8472
Ho. La mia idea era quella di creare una nuova classe 'MutableString', e implementare molte delle tradizionali operazioni spazzatura su di essa (per esempio, la divisione' String' di fastpath), e poi avere un metodo 'toString (from, to)' che crea un'istanza "view" che è di tipo 'String'. Potrei farlo. Ma ciò richiederebbe il refactoring completo della nostra applicazione e l'uso di 'MutableString's ovunque possibile. È una buona idea, ma ho voluto esplorare prima le alternative. – SergioTCG
Sei consapevole che tutte queste cose esistono già? Ci sono 'CharBuffer' e' StringBuilder', essendo entrambi una specie di 'String' mutabile (a meno che tu non abbia creato una vista immutabile), ci sono metodi per creare sottoserie leggere di essi e tutti implementano' CharSequence', l'interfaccia ' 'su cui funziona il pacchetto regex, che implementa effettivamente l'operazione' split'. E mentre sembra * il contenuto dei caratteri viene copiato tutto il tempo durante la conversione tra 'String's,' CharBuffer's e 'StringBuilder's quando si guarda il codice sorgente, HotSpot ha delle ottimizzazioni speciali per loro ... – Holger