Ich habe eine Frage untersucht, die mir vorgestellt wurde: Wie schreibe ich eine Funktion, die eine Zeichenfolge als Eingabe verwendet und eine Zeichenfolge mit Leerzeichen zwischen den Zeichen zurückgibt. Die Funktion soll geschrieben werden, um die Leistung zu optimieren, wenn sie tausende Male pro Sekunde aufgerufen wird.String.Join Leistungsproblem in C#
Ich weiß, dass .net eine Funktion hat
String.Join
genannt, auf die ich als Separator in dem Raum Charakter passieren kann mit der Original-Zeichenkette zusammen.Abgesehen von der Verwendung von
String.Join
kann ich die KlasseStringBuilder
verwenden, um Leerzeichen nach jedem Zeichen anzuhängen.Eine andere Möglichkeit, diese Aufgabe auszuführen, besteht darin, ein Zeichenarray mit 2 * n-1 Zeichen zu deklarieren (Sie müssen n-1 Zeichen für die Leerzeichen hinzufügen). Das Zeichenarray kann in eine Schleife gefüllt und dann an die Zeichenfolge
constructor
übergeben werden.
Ich habe einige .net-Code geschrieben, dass jeder dieser Algorithmen eine Millionen mal jeweils mit dem Parameter "Hello, World"
und Maßnahmen läuft, wie lange dauert es auszuführen. Methode (3) ist viel, viel schneller als (1) oder (2).
Ich weiß, dass (3) sollte sehr schnell sein, weil es vermeidet, zusätzliche String-Verweise zu erstellen, um Müll gesammelt werden, aber es scheint mir, dass eine integrierte. NET-Funktion wie String.Join
sollte gute Leistung erbringen. Warum ist die Verwendung von String.Join
so viel langsamer als die Arbeit mit der Hand?
public static class TestClass
{
// 491 milliseconds for 1 million iterations
public static string Space1(string s)
{
return string.Join(" ", s.AsEnumerable());
}
//190 milliseconds for 1 million iterations
public static string Space2(string s)
{
if (s.Length < 2)
return s;
StringBuilder sb = new StringBuilder();
sb.Append(s[0]);
for (int i = 1; i < s.Length; i++)
{
sb.Append(' ');
sb.Append(s[i]);
}
return sb.ToString();
}
// 50 milliseconds for 1 million iterations
public static string Space3(string s)
{
if (s.Length < 2)
return s;
char[] array = new char[s.Length * 2 - 1];
array[0] = s[0];
for (int i = 1; i < s.Length; i++)
{
array[2*i-1] = ' ';
array[2*i] = s[i];
}
return new string(array);
}
Update: Ich habe mein Projekt auf „Release“ Modus und aktualisiert meine verstrichenen Zeiten in der Frage entsprechend.
Wenn Sie Leistung vergleichen, sind Sie in Release mit Optimierungen auf bauen? – Servy
Wenn Sie den StringBuilder in Option 2 erstellen, können Sie eine Anfangskapazität von 2 * n-1 übergeben, was verhindern sollte, dass er seinen internen Puffer für größere Strings neu erstellt und kopiert. – Servy
@Servy, ich habe einfach ein neues Console-Projekt in Visual Studio 2010 erstellt. –