A che punto utilizzando uno StringBuilder diventare insignificanti o un overhead?

StackOverflow https://stackoverflow.com/questions/550702

  •  23-08-2019
  •  | 
  •  

Domanda

Recentemente mi sono trovato utilizzando StringBuilder per tutte le concatenazioni di stringhe, grandi e piccoli, tuttavia in una prova di prestazione recente ho scambiato fuori del stringOut = stringa1 + un collega "" string2 di concatenazione stile (usato in un ciclo + 10000X con lo StringBuilder viene newed ogni volta) per uno StringBuilder solo per vedere che differenza farebbe in una concatenazione minore.

ho trovato, nel corso di molti percorsi del test delle prestazioni, il cambiamento è stato sia insignificante maggiore o minore a prescindere dalla concatenazione o StringBuilder (riaffermare questo è stato per piccoli concatenazioni).

A che punto la 'Newing up' di un oggetto StringBuilder negare i vantaggi di utilizzare uno?

È stato utile?

Soluzione

La regola che seguo è -

Usa uno StringBuilder quando il numero di concatenazioni non è noto al momento della compilazione.

Quindi, nel tuo caso ogni StringBuilder è stato solo l'aggiunta di un paio di volte e poi essere scartata. Che non è proprio la stessa come qualcosa di simile

string s = String.Empty;
for (int i = 0; i < 10000; ++i)
{
    s += "A";
}

Quando si utilizza uno StringBuilder potrebbe drasticamente migliorare le prestazioni in quanto si sarebbe altrimenti essere costantemente assegnano nuova memoria.

Altri suggerimenti

Sono sicuro che ho un'altra risposta in cui ho postato solo un link rel="noreferrer"> e poi la sua sintesi, ma qui andiamo di nuovo.

  • utilizzare Sicuramente StringBuilder quando si concatenare in un ciclo non banale - soprattutto se non si sa per certo (al momento della compilazione) quante iterazioni farete attraverso il ciclo. Ad esempio, la lettura di un file di un carattere alla volta, costruendo una stringa, come si va con l'operatore + = è potenzialmente prestazioni suicidio.

  • utilizzare Sicuramente l'operatore di concatenazione quando si può (essere letti) specificare tutto ciò che ha bisogno di essere concatenati in una dichiarazione. (Se si dispone di una serie di cose per concatenare, considerare chiamando String.Concat esplicitamente -. O String.Join se avete bisogno di un delimitatore)

  • Non abbiate paura di rompere letterali in parecchi pezzi concatenati - il risultato sarà lo stesso. È possibile aiutare la leggibilità rompendo un lungo letterale in diverse linee, per esempio, senza alcun danno per le prestazioni.

  • Se avete bisogno dei risultati intermedi del concatenamento per qualcosa di diverso alimentando la prossima iterazione del concatenamento, StringBuilder non sta andando per aiutarvi. Per esempio, se si costruisce un nome completo da un nome e un cognome, e quindi aggiungere un terzo pezzo di informazioni (il soprannome, forse) fino alla fine, sarà possibile usufruire solo di utilizzare StringBuilder se non lo fanno bisogno la stringa (nome + cognome) per altri scopi (come facciamo l'esempio che crea un oggetto Person).

  • Se v'è solo un paio di concatenazioni da fare, e si vuole veramente fare loro nel bilancio separato, in realtà non importa quale direzione si va. Da che parte è più efficace dipenderà dal numero di concatenazioni le dimensioni delle stringhe coinvolti, e che ordine stanno concatenato. Se si crede davvero quel pezzo di codice per essere un collo di bottiglia delle prestazioni, profilo o punto di riferimento entrambe le cose.

A volte vale la pena guardare al documentazione :

  

Le prestazioni di una concatenazione   operazione per una stringa o   oggetto StringBuilder dipende da come   spesso un'allocazione di memoria si verifica. UN   operazione concatenazione di stringhe sempre   alloca memoria, mentre un   operazione di concatenazione StringBuilder   solo alloca memoria se il   tampone oggetto StringBuilder è troppo   piccola per accogliere i nuovi dati.   Di conseguenza, la classe String è   preferibile che una concatenazione   operazione se un numero fisso di stringa   gli oggetti sono concatenati. In ciò   caso, l'individuo concatenazione   operazioni potrebbero anche essere combinati in   un'unica operazione dal compilatore. UN   oggetto StringBuilder è preferibile   un'operazione di concatenazione se un   numero arbitrario di stringhe sono   concatenato; per esempio, se un ciclo   concatena un numero casuale di   stringhe di input dell'utente.

Nel tuo esempio, v'è un solo concatenazione di ogni stringa di output, in modo da StringBuilder si guadagna nulla. Si dovrebbe usare StringBuilder nei casi in cui si sta aggiungendo al stessa stringa più volte, per esempio:.

stringOut = ...
for(...)
    stringOut += "."
    stringOut += string2

La mia regola è semplice.

  1. Se ragionevolmente possibile scrivere una singola espressione che produce la finale, quindi utilizzare +.
  2. Se non è possibile (a causa sia della dimensione o la variabilità), quindi usare StringBuilder.

Nella mia esperienza, espressioni come:

"Id: " + item.id + " name: " + item.name

può essere scritto e compreso molto più facilmente che:

StringBuilder sb = new StringBuilder();
sb.append("Id: ").append(item.id);
sb.append(" name: ").append(item.name);

(seguito utilizzando la stringa da sb dove l'espressione di cui sopra sarebbe stato scritto), e si comporta altrettanto bene (suggerimento: guardare il codice compilato per capire perché)

D'altra parte, quando c'è bisogno di accumulare una stringa nel tempo (come il programma viene eseguito) o lo spazio (composta da valori provenienti da diverse parti del codice), in un modo che è poco pratico di scrivere come un unico espressione-line, quindi StringBuilder evita il sovraccarico (tempo e memoria-zangolatura) di:

String s = somethingExpression;
...
s += someOtherExpression;
...
s += yetAnotherExpression;
...

MSDN :

  

[L] a classe String è preferibile per un   operazione concatenazione se un determinato   Numero di oggetti String sono   concatenati. In tal caso, la   operazioni di concatenazione individuali   potrebbe anche essere combinati in un unico   funzionamento dal compilatore. UN   oggetto StringBuilder è preferibile   un'operazione di concatenazione se un   numero arbitrario di stringhe sono   concatenato; per esempio, se un ciclo   concatena un numero casuale di   stringhe di input dell'utente.

Credo che la risposta è "dipende" - se si sta concatenando all'interno di un ciclo con più di una manciata di iterazioni poi uno StringBuilder sarà quasi sempre fornire prestazioni migliori, ma l'unico modo per sapere con certezza è quello di realtà profilo .

C'è un articolo interessante su questo oltre a Coding Horror . Jeff ha ottenuto i seguenti risultati per 100.000 iterazioni su un dual core 3.5 GHz Core 2 Duo:

 Simple Concatenation    - 606 ms
 String.Format           - 665 ms
 string.Concat           - 587 ms
 String.Replace          - 979 ms
 StringBuilder           - 588 ms

Dot Net Perls :

Quando usare StringBuilder?

StringBuilder è interamente un'ottimizzazione, e offre miglioramenti logici stringa concatenazione oltre alla sua implementazione interna. Detto questo, è fondamentale utilizzare correttamente nelle applicazioni ad alte prestazioni e siti web.

A volte, è bene utilizzare piccoli cicli di 4 o meno iterazioni con semplici Inserto stringa. Tuttavia, in casi limite questo può essere disastroso. Piano per il vostro casi limite con StringBuilder.

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