2012-01-22 12 views
22

Può essere Sono i capelli scissione, ma mi chiedevo nel seguente caso:Ancora una volta sulla stringa aggiunta vs concat vs +

String newString = a + b + c; //case 1 


String newString = a.concat(b).concat(c); //case 2 

StringBuilder newString = new StringBuilder(); //case 3 
newString.append(a); 
newString.append(b);  
newString.append(c); 

Quale è il migliore da usare?

Migliore intendo in in qualsiasi modo.

Leggendo questi, altri posti dicono che il caso 3 non è prestazioni ottimali saggio, altri questo caso 1 finiranno nel caso 3 ecc

Per essere più specifici.

Ad esempio, mettendo tutto a parte, quale stile è più adatto per vederlo da un altro programmatore se si dovesse mantenere il suo codice?

O quale consideri più efficiente in termini di programmazione?
Oppure si potrebbe pensare è più veloce ecc.

Non so come altro esprimere questo.

Una risposta come ad es. il caso 3 può essere più veloce ma la maggior parte dei programmatori preferisce il caso 1 perché è più leggibile è accettato anche se è in qualche modo ben elaborato

+2

Non mi dispiace il downvote. Mi dispiace molto l'anonimo downvote – Cratylus

+0

Questa domanda è probabilmente un dupe di pochi altri. (Votato come nessuno è stato collegato a un duplicato.) –

+0

@Cratylus, Vorrei poter continuare a eludere il tuo commento ancora e ancora. Ma chi se ne frega, SO non è così senza anonimi downvotes. – 3bdalla

risposta

19

Caso 1 è conciso, esprime l'intento chiaramente, ed è equivalente al caso 3.

Il caso 2 è meno efficiente e anche meno leggibile.

Il caso 3 è quasi efficiente quanto il caso 1, ma più lungo e meno leggibile.

L'utilizzo del caso 3 è preferibile solo quando è necessario concatenare un ciclo. Altrimenti, il compilatore compila il caso 1 al caso 3 (tranne che costruisce StringBuilder con new StringBuilder(a)), il che lo rende ancora più efficiente del tuo caso 3).

+2

+1: il caso 2 crea un oggetto temporaneo, proprio come gli altri casi, quindi non è chiaro che sia meno efficiente, ma è meno probabile che sia chiaro. (In parte perché è il meno comune da usare) –

+0

Ha 1 oggetto temporaneo (beh 2 infatti, se contate il char array) perché ci sono solo 3 stringhe da concatenare. Se aggiungi più stringhe, avrai un altro oggetto temporaneo per stringa. –

+1

Concordato che non sia scalabile. Per 'a.concat (b)' è in realtà leggermente migliore. –

2

Il caso 3 è migliore in molti aspetti. Nel caso 3, non si termina la creazione di 3 oggetti stringa. A causa dell'immutabilità della stringa, 2 avrà un sovraccarico nella creazione di oggetti stringa per ogni + (o) concat.

MODIFICA: rileggere il documento e concordare con la maggior parte dei commenti, il caso 1 è il caso3.

+0

E di solito quando si fa una manipolazione del testo in cui le prestazioni sono importanti, si sta lavorando con (a) un volume molto più grande di operazioni; e (b) operazioni più complesse come la ricerca e l'inserimento o l'eliminazione di testo. – user268396

+2

Le JVM moderne convertono il caso 1 in caso 3 in runtime, quindi non ci saranno 3 oggetti String. Ma se ci sono molte concatenazioni sequenziali (in istruzioni diverse) o in un ciclo, allora sì ogni istruzione crea una nuova stringa immutabile. –

+0

Grazie Amir! accetto e aggiornato la mia risposta. – kosa

7

Caso 3 è la forma più prestazioni, ma la JVM converte caso da 1 a 3. caso

Ma credo che il caso 2 è il peggiore, non è così leggibile come il caso 1 e non come eseguire come caso 3

Se si desidera concatenere la stringa in un ciclo, utilizzare solo il caso 3, è possibile testare facilmente il guadagno di prestazioni, ma se non è in un ciclo (o non si aggiungono molte stringhe in una sequenza), esse sono quasi la stessa.

I casi che si impegna a non utilizzare l'operatore + sono:

String a = ""; 
for (String x : theStrings) { 
    a += x; 
} 

o

String a = b + c; 
a = a + d; 
a = a + e; 
a = a + f; 
1

Per casi semplici, l'utilizzo di + è chiaramente più leggibile.

Per casi più rari, StringBuilder ha senso. Se stai dividendo tra le linee, allora + può essere rapidamente un fattore di prestazioni. I loop passano da O (n) performance a O (n^2) - non è un problema se n è piccolo, ma un grosso problema se n può essere grande in circostanze scomode (forse quando si fa qualcosa di critico, o quando qualcuno è malizioso).

Contrariamente alle altre risposte, se hai solo tre stringhe, concat potrebbe essere il vincitore delle prestazioni. Sono mentale? No. Considera le altre due opzioni. Stai creando un oggetto StringBuilder, con un array. L'aggiunta delle stringhe potrebbe richiedere la sostituzione dell'array e alla fine dell'array potrebbero esserci dei bit dispari (la mancanza di una certa granularità nell'allocazione, quindi alcuni extra char s potrebbero aumentare o meno l'utilizzo della memoria). Puoi calcolare la capacità necessaria se odi tutti quelli che leggono il tuo codice. Caso migliore, due array (uno per StringBuilder, uno per il String (senza condivisione per gli ultimi otto anni)) ciascuno della dimensione del testo del risultato e di altri due oggetti (StringBuilder e String). Ora per il concat si assegnerà agli oggetti String con due array, ma il primo array sarà c.length() più corto. È una vittoria! Bene, non per la leggibilità.

Declinazione di responsabilità: JVM può eseguire l'ottimizzazione selvaggia, inclusa l'allocazione dello stack dopo l'analisi di escape e l'involucro speciale delle classi principali. Sono più propensi a ottimizzare il codice comune e semplice rispetto al codice offuscato a mano.