Sebbene sia le stringhe che gli interi siano immutabili, non sono la stessa cosa. Le stringhe sono tipi di riferimento immutabili; gli interi sono tipi di valori immutabili.
Se si dispone di una variabile stringa, s
, allora mantiene semplicemente un riferimento (un puntatore) alla posizione nell'heap in cui è archiviato quell'oggetto stringa. Se cambi la stringa a cui fa riferimento s
, allora potenzialmente un nuovo oggetto stringa viene creato sull'heap e quello originale è idoneo per la garbage collection se non ci sono altri riferimenti a esso.
Se tuttavia hai una variabile int
, i
, allora contiene il valore intero. Se cambi il numero detenuto da i
, allora quel valore cambia. Non c'è nessuna nuova allocazione dell'heap.
Certamente non è il caso che se si modificano le stringhe "il GarbageCollector deve raccoglierle tutto il tempo". Il garbage collector viene eseguito solo quando è necessario; è abbastanza probabile che durante la vita della tua app, non funzionerà mai. E anche quando viene eseguito, può essere molto veloce e non causare problemi di prestazioni. Non sto dicendo che non abbia mai problemi di prestazioni; ma sto dicendo che cambiare continuamente le stringhe non garantisce i problemi di prestazioni.
Modifica
Riguardo a StringBuilder
, questo è un problema di copia della memoria; non una raccolta di rifiuti. A titolo di esempio, prendere in considerazione il seguente codice:
var strings = GetListOf1000StringsEach100CharactersLong();
var finalString = "";
foreach (var item in strings)
{
finalString += item;
}
Che cosa succede quando corri quello è:
- La prima volta, i 100 caratteri nelle stringhe [0] vengono copiati in una nuova posizione, a cui fa riferimento
finalString
.
- La seconda volta attraverso il ciclo, quei 100 caratteri in
finalString
, più il 100 in strings[1]
vengono copiati in una nuova posizione e finalString
aggiornati in quel punto.
- La terza volta, quei 200 caratteri in
finalString
, più il 100 in strings[2]
vengono copiati in una nuova posizione e finalString
aggiornati in quel punto ...
- Nell'ultimo passaggio, quei 99900 caratteri in
finalString
, più il 100 in strings[999]
vengono copiati in una nuova posizione e finalString
aggiornati in quel punto!
Mentre scorre, il numero di caratteri che deve essere copiato aumenta e questi stessi caratteri vengono copiati più e più volte. Questo è un enorme problema di prestazioni. StringBuilder
lo risolve semplicemente memorizzando i riferimenti alle stringhe originali e facendo solo quella copia una volta, quando viene chiamato ToString()
. Questo dà una grande spinta alle prestazioni. Ma non è correlato alla garbage collection.