2017-07-19 1 views
0

Nicht wirklich eine Frage, aber ich habe keine Antwort gefunden, so habe ich selbst einige Tests durchgeführt, und dachte, andere könnten davon profitieren.C# String.PadRight Leistung vs Verkettung String + Teilstring Pad-Zeichen

zunächst die Frage:

Wenn ein (viel) Strings mit einer vordefinierten Länge mit einem vordefinierten Zeichen Klotzen, ist es schneller String.PadRight() zu verwenden oder die Zeichenkette mit der Teilzeichenfolge einer voreingestellten Folge von verketten Füllzeichen?

+0

Es ist nicht klar, was Sie versuchen zu pad oder verketten. Diese Frage kann also nur von Ihnen beantwortet werden. –

+0

Ich bin mir ziemlich sicher, dass Sie die Schwierigkeit eines korrekten und aussagekräftigen Benchmarks sehr unterschätzt haben. - Vielleicht möchten Sie auch einen Blick auf die C# Quellen werfen! – TaW

+0

@TimSchmelter Nun, ich hatte ursprünglich beide Frage und die Antwort unten in einem Post, bis ich sah, dass ich sie direkt aufteilen konnte. Aber da ich meine Antwort zur gleichen Zeit wie die Frage gepostet habe, bin ich davon ausgegangen, dass derjenige, der die Frage nicht alleine gefunden hat, mehr Informationen darüber bekommen könnte, was genau mein Ziel ist;) –

Antwort

2

Ich habe den Test selbst durchgeführt, nachdem ich keine Antwort gefunden habe (das ist der Grund für den Beitrag an erster Stelle).

Meine Ergebnisse waren wie (ähnlich über mehrere Läufe) folgt

direct String.PadRight average: 29,291921 ms. 
String.PadRight average:  32,328434 ms. 
Custom PadRight average:  27,066596 ms. 

mit

private const int Iterations = 500; 
private const int NumStrings = 250000; 
private const int TestStringLength = 50; 

für einen Test, in dem ich erzeugten NumStrings zufälligen Zeichenfolgen von weniger als TestStringLength Zeichen und gepolstert dann alle sie zu TestStringLength mit Leerzeichen.

So scheint die substring-basierte Polsterung schneller gewesen zu sein (aber natürlich weniger vielseitig). Interessanterweise wird dieser Trend umgekehrt, je weniger Strings gepolstert werden und je weniger Iterationen ausgeführt werden. Dann wird String.PadRight schneller schneller.

Der Testcode (here a dotnetfiddle version [zählt reduziert, um es dort funktioniert, und Sie können die Ergebnisse, die Sie dort nicht trauen, sie eine Menge von Ausführung Ausführung unterscheiden]):

#region Performance Test 
private const int Iterations = 500; 
private const int NumStrings = 250000; 
private const int TestStringLength = 50; 

private static string EmptyLine; 

public static string PadRight(string input) 
{ 
    return input.PadRight(TestStringLength, ' '); 
} 
public static string PadRight2(string input) 
{ 
    return input + EmptyLine.Substring(0, TestStringLength - input.Length); 
} 
#endregion // Performance Test 

mit der Schleife sein

#region Performance Test 

EmptyLine = String.Join("", Enumerable.Repeat(" ", TestStringLength)); 

var random = new System.Random(); 
StringBuilder temp = new StringBuilder(); 
string[] randomStrings = new string[NumStrings]; 
double[] averageDirect = new double[Iterations]; 
double[] averageStandard = new double[Iterations]; 
double[] averageCustom = new double[Iterations]; 

// init random strings 
for (int i = 0; i < NumStrings; ++i) 
{ 
    temp.Clear(); 
    for (int k = 0; k < random.Next(0, TestStringLength); ++k) 
    { 
     temp.Append((char)('!' + random.Next(0, 93))); 
    } 
    randomStrings[i] = temp.ToString(); 
} 

var timer = new Stopwatch(); 
string padded; 

for (int counter = 0; counter < Iterations; ++counter) 
{ 
    timer.Reset(); 

    timer.Start(); 
    for (int i = 0; i < NumStrings; ++i) 
    { 
     padded = PadRight2(randomStrings[i]); 
    } 
    timer.Stop(); 
    averageCustom[counter] = timer.Elapsed.TotalMilliseconds; 

    timer.Reset(); 

    timer.Start(); 
    for (int i = 0; i < NumStrings; ++i) 
    { 
     padded = PadRight(randomStrings[i]); 
    } 
    timer.Stop(); 
    averageStandard[counter] = timer.Elapsed.TotalMilliseconds; 

    timer.Reset(); 

    timer.Start(); 
    for (int i = 0; i < NumStrings; ++i) 
    { 
     padded = randomStrings[i].PadRight(TestStringLength, ' '); 
    } 
    timer.Stop(); 
    averageDirect[counter] = timer.Elapsed.TotalMilliseconds; 
} 

Console.WriteLine($"direct String.PadRight average: {averageDirect.Average()} ms."); 
Console.WriteLine($"String.PadRight average: {averageStandard.Average()} ms."); 
Console.WriteLine($"Custom PadRight average: {averageCustom.Average()} ms."); 

#endregion // Performance Test 
+0

Side -note: Ich kann empfehlen, [BenchmarkDotNet] (http://benchmarkdotnet.org/) für solche Tests zu verwenden. Einfach zu bedienen mit viel genaueren Ergebnissen. Denken Sie daran, Tests auszuführen, die als Release kompiliert wurden und keinen angehängten Debugger haben (zum Beispiel als Konsolenanwendung, die nicht in Visual Studio gestartet wird). Natürlich sollten die Tests selbst nur testen, was sie sollten und nicht unzusammenhängenden Code (zB was für beide Ansätze gleich ist). –