2017-07-19 18 views
0

質問はありませんが、回答が見つからなかったので、いくつかのテストを自分で実行しました。C#String.PadRightパフォーマンスと連結文字列+パッド文字の部分文字列

最初の質問:事前に定義された文字で事前に定義された長さに文字列(の多く)をパディングする場合

、それはString.PadRight()を使用するかの事前設定文字列の部分文字列と文字列を連結する高速ですパディング文字ですか?

+0

あなたがパッドしたり連結しているものは明確ではありません。だから、この質問は自分でのみ答えることができます。 –

+0

私は、正確で意味のあるベンチマークの困難さを大幅に取り除いてくれると確信しています。 - また、C#のソースを見てみたいかもしれません! – TaW

+0

@TimSchmelterまあ、もともと私はそれらを直接分割することができるまで、質問と答えを1つの投稿に入れました。しかし、私は自分の答えを質問と同時に掲示して以来、誰かが質問だけで十分ではないと思った人は、私の目標が答えであるかどうかについてもっと多くの情報を得ることができたと思っていました;) –

答えて

2

私は答えが見つからなかったので、自分でテストを実行しました(これが最初の投稿の理由です)。

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

次のように私の結果は、(複数の実行を超えると類似)した

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

I未満TestStringLength文字のNumStringsランダムな文字列を生成し、その後のすべてを埋めているテストのためにそれらを空白でTestStringLengthにします。

したがって、部分文字列ベースのパディングはより高速になっているように見えますが(もちろん汎用性は低いです)興味深いことに、この傾向は逆になり、少ない文字列が埋められ、繰り返し回数が少なくなります。その後、String.PadRightはすばやく高速になります。

テストコードは(here a dotnetfiddle version [減少数は、それが動作させるために、そしてあなたがそこに着く結果を信頼することはできません、彼らは実行するために実行からLOTを変える]):と

#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 

ループがある

#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

の読書を楽しむことができます注:このようなテストには[BenchmarkDotNet](http://benchmarkdotnet.org/)の使用をお勧めします。はるかに正確な結果で使いやすい。リリースとしてコンパイルされたテストを実行し、デバッガが接続されていない状態で実行することを忘れないでください(たとえば、ビジュアルスタジオでスタンドされていないコンソールアプリケーションなど)。もちろん、テスト自体は、無関係なコードではなく、何をすべきかをテストすべきです(つまり、両方のアプローチで同等である)。 –