String.Format wird StringBuilder
intern verwendet ... so logisch, dass die Idee entsteht, dass es aufgrund des höheren Overheads etwas weniger performant wäre. Eine einfache String-Verkettung ist jedoch die schnellste Methode, um einen String zwischen zwei anderen zu injizieren ... in erheblichem Maße. Dieser Beweis wurde von Rico Mariani vor Jahren in seinem allerersten Performance Quiz demonstriert. Einfache Tatsache ist, dass Verkettungen ... wenn die Anzahl der String-Teile bekannt ist (ohne Einschränkung ... Sie könnten tausend Teile verketten ... solange Sie wissen, dass es immer 1000 Teile sind) ... immer schneller als StringBuilder
oder String sind. Format. Sie können mit einer einzelnen Speicherzuordnung und einer Reihe von Speicherkopien durchgeführt werden. Hier ist der Beweis
Und hier ist der eigentliche Code für einige String.Concat-Methoden, die letztendlich FillStringChecked aufrufen, das Zeiger zum Kopieren des Speichers verwendet (extrahiert über Reflector):
public static string Concat(params string[] values)
{
int totalLength = 0;
if (values == null)
{
throw new ArgumentNullException("values");
}
string[] strArray = new string[values.Length];
for (int i = 0; i < values.Length; i++)
{
string str = values[i];
strArray[i] = (str == null) ? Empty : str;
totalLength += strArray[i].Length;
if (totalLength < 0)
{
throw new OutOfMemoryException();
}
}
return ConcatArray(strArray, totalLength);
}
public static string Concat(string str0, string str1, string str2, string str3)
{
if (((str0 == null) && (str1 == null)) && ((str2 == null) && (str3 == null)))
{
return Empty;
}
if (str0 == null)
{
str0 = Empty;
}
if (str1 == null)
{
str1 = Empty;
}
if (str2 == null)
{
str2 = Empty;
}
if (str3 == null)
{
str3 = Empty;
}
int length = ((str0.Length + str1.Length) + str2.Length) + str3.Length;
string dest = FastAllocateString(length);
FillStringChecked(dest, 0, str0);
FillStringChecked(dest, str0.Length, str1);
FillStringChecked(dest, str0.Length + str1.Length, str2);
FillStringChecked(dest, (str0.Length + str1.Length) + str2.Length, str3);
return dest;
}
private static string ConcatArray(string[] values, int totalLength)
{
string dest = FastAllocateString(totalLength);
int destPos = 0;
for (int i = 0; i < values.Length; i++)
{
FillStringChecked(dest, destPos, values[i]);
destPos += values[i].Length;
}
return dest;
}
private static unsafe void FillStringChecked(string dest, int destPos, string src)
{
int length = src.Length;
if (length > (dest.Length - destPos))
{
throw new IndexOutOfRangeException();
}
fixed (char* chRef = &dest.m_firstChar)
{
fixed (char* chRef2 = &src.m_firstChar)
{
wstrcpy(chRef + destPos, chRef2, length);
}
}
}
Also dann:
string what = "cat";
string inthehat = "The " + what + " in the hat!";
Genießen!