2016-11-16 2 views
0

2つの異なる実装でパフォーマンスをテストしたいので2つのテストを行いました。文字列のLINQでのパフォーマンス

これは私のコードです:

[TestMethod] 
    public void TestMethod1() 
    { 
     string text = "I want to find the number (30)"; 
     var startNumber = text.IndexOf('('); 
     var trimmed = text.Trim(')'); 
     var number = trimmed.Substring(startNumber).Trim('('); 

     Assert.AreEqual("30", number); 
    } 

    [TestMethod] 
    public void TestMethod2() 
    { 
     string text = "I want to find the number (30)"; 
     var lambdaNumber = text.Where(x => Char.IsNumber(x)).ToArray(); 
     var joined = string.Join("", lambdaNumber); 

     Assert.AreEqual("30", joined); 
    } 

結果は(ラムダ式で)TestMethod2がTestMethod1よりも高速であるということです。テストエクスプローラによると。

TestMethod1 = 2msの TestMethod2 = < 1msの

私は、各テストでストップウォッチを追加しようとすると、TestMethod1ははるかに最速です。

この動作のパフォーマンスを適切にテストするにはどうすればよいですか?

EDIT:

は、私は方法が同じ操作を実行していないという事実を感謝しています。そこで私は、代わりに次のように作成しました:

[TestMethod] 
    public void TestMethod1() 
    { 
     var sw = new Stopwatch(); 
     sw.Start(); 

     var number = string.Empty; 
     var counter = 0; 
     while (counter < 100000) 
     { 
      number = string.Empty; 
      string text = "I want to find the number (30)"; 
      foreach (var c in text.ToCharArray()) 
      { 
       int outNumber; 
       if (int.TryParse(c.ToString(), out outNumber)) 
        number += c.ToString(); 
      } 
      counter++; 
     } 

     sw.Stop(); 

     Assert.AreEqual("30", number); 
    } 

    [TestMethod] 
    public void TestMethod2() 
    { 
     var sw = new Stopwatch(); 
     sw.Start(); 

     var joined = String.Empty; 
     var counter = 0; 
     while (counter < 100000) 
     { 
      string text = "I want to find the number (30)"; 
      var lambdaNumber = text.Where(x => Char.IsNumber(x)).ToArray(); 
      joined = string.Join("", lambdaNumber); 
      counter++; 
     } 

     sw.Stop(); 

     Assert.AreEqual("30", joined); 
    } 

ストップウォッチによると、結果は以下の通りである:私は同意したよう TestMethod1 = 19ms TestMethod2 = 7MS

は、すべての返信用

+3

ループを1から10000まで実行すると、それらの間にストップウォッチが両方とも実行され、どちらが速いかがわかります。 – mybirthname

+5

2つの方法が同じではない、つまり "10 20(30)"のように入力した場合、最初の値は "30"を返しますが、2番目の値は "102030"を返します。 – stuartd

+4

最初の方法はかっこを検索します。 2番目の方法は数字を検索します。あなたはトマトとリンゴを比較しています。 – Amy

答えて

1

をありがとうほとんどのコメントで、単体テストなしでテストを立てることが役立つと思いました。 LINQで作業する場合は、LINQPad(無料の標準版)を使用して、このようなテストやその他の小さなコードブロックを実行してください。 Regexを含むように拡張され、100000ループに増やされたテストです。

void Main() 
{ 
    string text = "I want to find the number (30)"; 

    Stopwatch sw = Stopwatch.StartNew(); 

    for (int i = 0; i < 100000; i++) 
    { 
     TestMethod1(); 
    } 

    sw.Elapsed.TotalMilliseconds.Dump("Substring no parameter");  
    sw = Stopwatch.StartNew(); 

    for (int i = 0; i < 100000; i++) 
    { 
     TestMethod1(text); 
    } 

    sw.Elapsed.TotalMilliseconds.Dump("Substring parameter"); 
    sw = Stopwatch.StartNew(); 

    for (int i = 0; i < 100000; i++) 
    { 
     TestMethod2(); 
    } 

    sw.Elapsed.TotalMilliseconds.Dump("LINQ no parameter"); 
    sw = Stopwatch.StartNew(); 

    for (int i = 0; i < 100000; i++) 
    { 
     TestMethod2(text); 
    } 

    sw.Elapsed.TotalMilliseconds.Dump("LINQ parameter"); 
    sw = Stopwatch.StartNew(); 

    for (int i = 0; i < 100000; i++) 
    { 
     TestMethod3(text); 
    } 

    sw.Elapsed.TotalMilliseconds.Dump("Regex In"); 
    sw = Stopwatch.StartNew(); 

    for (int i = 0; i < 100000; i++) 
    { 
     TestMethod4(text); 
    } 

    sw.Elapsed.TotalMilliseconds.Dump("Regex Out"); 
    sw = Stopwatch.StartNew(); 
    sw.Stop(); 
} 

// Define other methods and classes here 
public void TestMethod1() 
{ 
    string text = "I want to find the number (30)"; 
    var startNumber = text.IndexOf('('); 
    var trimmed = text.Trim(')'); 
    var number = trimmed.Substring(startNumber).Trim('('); 
} 

public void TestMethod1(string text) 
{ 
    var startNumber = text.IndexOf('('); 
    var trimmed = text.Trim(')'); 
    var number = trimmed.Substring(startNumber).Trim('('); 
} 

public void TestMethod2() 
{ 
    string text = "I want to find the number (30)"; 
    var lambdaNumber = text.Where(x => Char.IsNumber(x)).ToArray(); 
    var joined = string.Join("", lambdaNumber); 
} 

public void TestMethod2(string text) 
{ 
    var lambdaNumber = text.Where(x => Char.IsNumber(x)).ToArray(); 
    var joined = string.Join("", lambdaNumber); 
} 

public void TestMethod3(string text) 
{ 
    var regex = new Regex(@"(\d+)"); 
    var match = regex.Match(text); 
    var joined = match.Captures[0].Value; 
} 

public Regex regex = new Regex(@"(\d+)"); 

public void TestMethod4(string text) 
{ 
    var match = regex.Match(text); 
    var joined = match.Captures[0].Value; 
} 

と結果:

Substring no parameter 
11.3526 

Substring parameter 
10.2901 

LINQ no parameter 
60.2359 

LINQ parameter 
56.5218 

Regex In 
301.1179 

Regex Out 
89.8345 

結論?我々はまだリンゴとオレンジをダイヤモンドと比較しています。正規表現はいくつか提案したほど速くはないようです。プロフェッショナルツールは、道のりです。

関連する問題