2015-11-24 14 views
10

Una domanda relativa alle considerazioni sulle prestazioni per String.substring. Prima di Java 1.7.0_06, il metodo String.substring() ha restituito un nuovo oggetto String che condivideva lo stesso array di caratteri sottostante dei genitori ma con offset e lunghezza diversi. Per evitare di mantenere una stringa di grandi dimensioni in memoria quando è stata necessaria solo una piccola stringa di essere tenuto, i programmatori utilizzato per scrivere codice come questo:String.substring() che effettua una copia del valore char [] sottostante

s = new String(queryReturningHugeHugeString().substring(0,3)); 

Da 1.7.0_06 in poi, non è stato necessario creare un nuovo String poiché nell'implementazione Oracle di String, le sottostringhe non condividono più il loro array di caratteri sottostanti.

La mia domanda è: possiamo fare affidamento su Oracle (e altri fornitori) per non tornare alla char[] condivisione in qualche versione futura, e semplicemente fare s = s.substr(...), o dovremmo creare una nuova stringa in modo esplicito nel caso qualche futura versione del JRE inizia a utilizzare nuovamente un'implementazione di condivisione?

+1

Non è una risposta esatta, ma una buona risposta qui http://stackoverflow.com/a/20275133/2796832 potrebbe aiutare. Forse se proprio ne hai bisogno potresti usare 'getValueLength' da quella risposta e usarlo per contrassegnare il tuo codice. –

+2

@JonahGraham, cattivo consiglio. Questo potrebbe rompersi già in Java-9: è previsto che l'array 'char []' sarà sostituito con 'byte []' lì. L'accesso ai campi JDK privati ​​tramite la riflessione non è una buona idea in generale. –

+0

@TagirValeev TBH Avevo pensato di mettere quel commento come risposta, ma mi ha fatto sentire a disagio. Sono sicuro che l'OP ha fatto un'analisi dettagliata per garantire che l'ulteriore complicazione nel loro codice non fosse un'ottimizzazione prematura. Tuttavia, non sono sicuro che il futuro lettore avrebbe la stessa cura e attenzione. Ad ogni modo, la tua risposta è buona +1 –

risposta

6

La rappresentazione reale di String è un dettaglio di implementazione interno, quindi non si può mai essere sicuri. Tuttavia, secondo i discorsi pubblici degli ingegneri Oracle (in particolare lo @shipilev) è molto improbabile che venga sostituito. Ciò è stato fatto non solo per combattere con possibili perdite di memoria, ma anche per semplificare gli interni di String. Con stringhe più semplici è più semplice implementare molte tecniche di ottimizzazione come String deduplication o Compact Strings.

+0

In realtà, l'esistenza della de-duplicazione delle stringhe mostra anche che non dobbiamo mai preoccuparci della rappresentazione della sottostringa. Se il garbage collector di una JVM è in grado di applicare patch alle stringhe per consentire alle istanze uguali di condividere lo stesso array, non è troppo esagerato supporre che sarebbe in grado di applicare anche le sottostringhe se un produttore JVM decide di tornare alla sottostringa condivisa (offset + lunghezza) rappresentazione. – Holger

Problemi correlati