ich den Quellcode des Open-Source-Projektes SignalR bin gerade, und ich sehe this diff code die „nicht String oder foreach in diesem heißen Code berechtigt ist, Verwenden Pfad“:„Verwenden String oder foreach nicht in diesem heißen Codepfad“
- public static string MakeCursor(IEnumerable<Cursor> cursors)
+ public static string MakeCursor(IList<Cursor> cursors)
{
- var sb = new StringBuilder();
- bool first = true;
- foreach (var c in cursors)
+ var result = "";
+ for (int i = 0; i < cursors.Count; i++)
{
- if (!first)
+ if (i > 0)
{
- sb.Append('|');
+ result += '|';
}
- sb.Append(Escape(c.Key));
- sb.Append(',');
- sb.Append(c.Id);
- first = false;
+ result += Escape(cursors[i].Key);
+ result += ',';
+ result += cursors[i].Id;
}
- return sb.ToString();
+ return result;
}
ich verstehe, warum foreach manchmal weniger effizient sein könnte, und warum ist es durch für ersetzt.
Allerdings habe ich gelernt und erlebt, dass der StringBuilder der effizienteste Weg zum Verketten von Strings ist. Ich frage mich also, warum der Autor sich dafür entschieden hat, es durch eine Standardverkettung zu ersetzen.
Was ist hier und im Allgemeinen falsch bei der Verwendung von StringBuilder?
Was denken Sie macht, dass 'foreach' ist weniger effizient als' for'? Es hängt von der Implementierung ab.Und ja, die Verwendung von wiederholten String-Verkettungen scheint hier eine schreckliche Idee zu sein - besonders wenn es viele Cursor gibt. –
Stimme stark mit Jon überein. Ich wäre überrascht, wenn die StringBuilder-Version schlechter als die Verkettungsversion wäre. Abhängig von der Anzahl der Schleifeniterationen kann es helfen, einige "versteckte" implizite Objektinitialisierungen zu verhindern, wenn der StringBuilder mit einer größeren Startkapazität initialisiert wird. Haben Sie beide Versionen gemessen/profiliert, um sie zu vergleichen? –
Sie sollten es [@dfowler] (http://stackoverflow.com/users/45091/dfowler) fragen :) –