Quando utilizzare StringBuilder?
-
22-07-2019 - |
Domanda
Comprendo i vantaggi di StringBuilder.
Ma se voglio concatenare 2 stringhe, suppongo che sia meglio (più veloce) farlo senza StringBuilder. È corretto?
A che punto (numero di stringhe) è meglio usare StringBuilder?
Soluzione
Ti consiglio caldamente di leggere The Sad Tragedy of Micro-Optimization Theater , di Jeff Atwood.
Tratta la concatenazione semplice rispetto a StringBuilder rispetto ad altri metodi.
Ora, se vuoi vedere alcuni numeri e grafici, segui il link;)
Altri suggerimenti
Ma se voglio concatinare 2 stringhe, quindi presumo che lo sia meglio (più veloce) di farlo senza StringBuilder. È corretto?
Questo è davvero corretto, puoi scoprire perché esattamente spiegato molto bene su:
http://www.yoda.arachsys.com/csharp/stringbuilder.html
Riassumendo: se puoi concatinare le stringhe in una volta, vai come
var result = a + " " + b + " " + c + ..
stai meglio senza StringBuilder perché viene creato solo su copia (la lunghezza della stringa risultante viene calcolata in anticipo.);
Per strutture come
var result = a;
result += " ";
result += b;
result += " ";
result += c;
..
nuovi oggetti vengono creati ogni volta, quindi dovresti considerare StringBuilder.
Alla fine l'articolo riassume queste regole pratiche:
Regole empiriche
Quindi, quando dovresti usare StringBuilder, e quando dovresti usare la stringa operatori di concatenazione?
Sicuramente usa StringBuilder quando stai concatenando in modo non banale loop - specialmente se non lo sai di sicuro (al momento della compilazione) quanti iterazioni che farai attraverso ciclo continuo. Ad esempio, leggere un file a personaggio alla volta, costruendo a stringa mentre procedi utilizzando l'operatore + = è potenzialmente un suicidio da prestazione.
Sicuramente usa la concatenazione operatore quando puoi (facilmente) specifica tutto ciò che deve essere concatenato in una dichiarazione. (Se tu avere una serie di cose da fare concatenare, prendere in considerazione la chiamata String.Concat esplicitamente - o String.Unisciti se hai bisogno di un delimitatore.)
Non abbiate paura di rompere i letterali in diversi bit concatenati: il il risultato sarà lo stesso. Puoi aiutare leggibilità rompendo un lungo letterale in più righe, ad esempio, con nessun danno alle prestazioni.
Se hai bisogno dei risultati intermedi della concatenazione per qualcosa altro che alimentare la prossima iterazione di concatenazione, StringBuilder non lo è ti aiuterà. Ad esempio, se costruisci un nome completo fin dall'inizio nome e cognome, quindi aggiungere a terza informazione (il soprannome, forse) fino alla fine, lo farai beneficiano solo dell'utilizzo di StringBuilder se non ti serve il (nome + cognome) stringa per altri scopi (come facciamo nell'esempio che crea un oggetto Person).
Se hai solo alcune concatenazioni da fare e tu vuoi davvero farli in dichiarazioni separate, non lo fa importa davvero da che parte vai. Quale modo è più efficiente dipenderà il numero di concatenazioni le dimensioni di stringa coinvolta e quale ordine sono concatenati. Se davvero credi che quel pezzo di codice sia un collo di bottiglia delle prestazioni, profilo o benchmark in entrambi i modi.
System.String è un oggetto immutabile - significa che ogni volta che modifichi il suo contenuto allocherà una nuova stringa e questo richiederà tempo (e memoria?). Usando StringBuilder modifichi il contenuto effettivo dell'oggetto senza assegnarne uno nuovo.
Quindi usa StringBuilder quando devi fare molte modifiche sulla stringa.
Non proprio ... dovresti usare StringBuilder se concateni stringhe di grandi dimensioni o hai molte concatenazioni, come in un ciclo.
Non esiste una risposta definitiva, solo regole empiriche. Le mie regole personali vanno in questo modo:
- Se si concatena in un ciclo, utilizzare sempre un
StringBuilder
. - Se le stringhe sono grandi, utilizzare sempre un
StringBuilder
. - Se il codice di concatenazione è ordinato e leggibile sullo schermo, probabilmente è ok.
In caso contrario, utilizzare unStringBuilder
.
Per parafrasare
Quindi conterai fino a tre, né più né meno. Tre sarà il numero che conterai e il numero del conteggio sarà tre. Quattro non conterai, né conterai due, tranne che poi procederai a tre. Una volta raggiunto il numero tre, che è il terzo numero, quindi lancia la tua bomba a mano santa di Antiochia
In genere utilizzo il generatore di stringhe per qualsiasi blocco di codice che comporterebbe la concatenazione di tre o più stringhe.
- Se concatenate le stringhe in un ciclo, dovreste considerare l'utilizzo di StringBuilder invece della normale String
- Nel caso in cui si tratti di una singola concatenazione, potresti non vedere affatto la differenza nei tempi di esecuzione
Ecco una semplice app di prova per dimostrare il punto:
class Program
{
static void Main(string[] args)
{
const int testLength = 30000;
var StartTime = DateTime.Now;
//TEST 1 - String
StartTime = DateTime.Now;
String tString = "test string";
for (int i = 0; i < testLength; i++)
{
tString += i.ToString();
}
Console.WriteLine((DateTime.Now - StartTime).TotalMilliseconds.ToString());
//result: 2000 ms
//TEST 2 - StringBuilder
StartTime = DateTime.Now;
StringBuilder tSB = new StringBuilder("test string");
for (int i = 0; i < testLength; i++)
{
tSB.Append(i.ToString());
}
Console.WriteLine((DateTime.Now - StartTime).TotalMilliseconds.ToString());
//result: 4 ms
Console.ReadLine();
}
}
Risultati:
-
30'000 iterazioni
- Stringa - 2000 ms
- StringBuilder - 4 ms
-
1000 iterazioni
- Stringa - 2 ms
- StringBuilder - 1 ms
-
500 iterazioni
- Stringa - 0 ms
- StringBuilder - 0 ms
Ma se voglio concatenare 2 stringhe, suppongo che sia meglio e più veloce farlo senza StringBuilder. È corretto?
Sì. Ma ancora più importante, è molto più leggibile usare una String
vaniglia in tali situazioni. Usarlo in un ciclo, d'altra parte, ha senso e può anche essere leggibile come la concatenazione.
I & # 8217; diffidare delle regole empiriche che citano specifici numeri di concatenazione come soglia. Usarlo in loop (e solo in loop) è probabilmente altrettanto utile, più facile da ricordare e ha più senso.
Finché puoi digitare fisicamente il numero di concatenazioni (a + b + c ...) non dovrebbe fare una grande differenza. N al quadrato (a N = 10) è un rallentamento di 100X, che non dovrebbe essere troppo male.
Il grosso problema è quando si stanno concatenando centinaia di stringhe. A N = 100, ottieni un rallentamento di 10000 volte. Il che è piuttosto male.
Non penso che ci sia una linea sottile tra quando usare o quando non farlo. A meno che, naturalmente, qualcuno abbia eseguito alcuni test approfonditi per scoprire le condizioni d'oro.
Per me, non userò StringBuilder se concatenerò solo 2 stringhe enormi. Se c'è un ciclo con un conteggio indeterminato, probabilmente lo farò, anche se il ciclo potrebbe essere un numero piccolo.
Non vale la pena utilizzare una singola concatenazione con StringBuilder. In genere ho usato 5 concatenazioni come regola empirica.
La classe StringBuilder fornisce allo sviluppatore una serie di metodi che consente la manipolazione di una stringa mutabile di caratteri, può essere utilizzata quando si desidera modificare una stringa senza creare un nuovo oggetto, eliminando così il problema di sovraccarico o collo di bottiglia della normale concatenazione di stringhe.
L'uso della classe StringBuilder può migliorare le prestazioni quando si concatenano molte stringhe insieme in un ciclo.
Di seguito è riportato un elenco di alcune operazioni che è possibile eseguire per manipolare una stringa utilizzando la classe StringBuilder in .NET
Aggiungi : aggiunge informazioni alla fine dell'attuale StringBuilder.
AppendFormat : sostituisce un identificatore di formato passato in una stringa con testo formattato.
Inserisci : inserisce una stringa o un oggetto nell'indice specificato dell'attuale StringBuilder.
Rimuovi : rimuove un numero specificato di caratteri dall'attuale StringBuilder.
Sostituisci : sostituisce un carattere specificato in un indice specificato.