Questione di stringhe

di Cristian Civera, in .NET,

Al WPC 2004 Francesco Balena mi ha incuriosito in un dettaglio e quindi sono andato a verificare.
Consideriamo questo codice:

string sep = String.Empty;
string s = String.Empty;
for (int x = 0; x < 100; x++) {
s += sep + x.ToString();
if (x == 0)
sep = ",";
}

E' un normale ciclo che concatena i numeri da 0 a 99 dividendoli con una virgola. Ormai si sa, contanerare le stringhe non è una buona pratica. Questo perché in .NET una stringa ha dimensioni fisse. Concatenarla con un'altra vuol dire allocare della nuova memoria per contenere la prima con la seconda. In questi casi quindi si consiglia di usare StringBuilder:

string sep = String.Empty;
StringBuilder sb = new StringBuilder();
for (int x = 0; x < 100; x++) {
sb.Append(sep);
sb.Append(x.ToString());
sep = ",";
}

Fin qui, niente di nuovo. Di nuovo c'è che ho tolto l'if che controlla se x è 0. Questo perché il codice assembler prodotto dal jitter è minore e si risparmiano cicli di macchina:

if (x == 0)
cmp dword ptr [ebp-10h],0 
jne 00000064
sep = ",";
mov eax,dword ptr ds:[01AA1330h]
mov ebx,eax

Anche se non siete esperti di asm: senza condizione risparmiamo due istruzioni ;-) Sicuramente vi sarete domandati (almeno io ho pensato così): ma in questo modo ad ogni ciclo del for creeremo inutilmente 99 stringhe con ','. Invece no. Il jitter è abbastanza intelligente per verificare che quella stringa non sia già stata caricata nello stack, ovviamente prestando attenzione che questa non venga utilizzata in modi differenti.
A dimostrazione di quanto detto, fatte una piccola console application e debuggate guardando il pannello disassembly. Se date un'occhiata al codice assembler corrispondente (VS.Net è molto comodo) e seguite il pannello del registro noterete che ad ogni ciclo ebx avrà sempre lo stesso valore equindi punterà sempre alla stessa allocazione di memoria (il punto di inizio della stringa).

Ringrazio Raffaele che m'ha aperto gli occhi su questi aspetti riempiendomi la testa durante il WPC :-D

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Nella stessa categoria
I più letti del mese