18

私は2つ持っていますIEnumerable<int>

IEnumerable<int> x;
IEnumerable<int> y;

y の int が x に存在するかどうかを判断する最良の方法は何ですか?
現在私は使用しています:

return x.Intersect<int>(y).Count() > 0;

ループしてそれぞれを個別にテストする方がはるかに高速でしょうか?

foreach (int i in x)
{
    foreach (int j in y)
    {
        if (i == j) return true;
    }
}
return false;

リストは比較的軽量で、x の int は 50 以下、y の int は 4 以下です。

4

5 に答える 5

0

この質問と最後の回答は、私の回答の時点で 1 年以上前のものです。ただし、私の調査結果は、受け入れられた回答とは異なります。ループは、Intersect.Any() を使用するよりも大幅に高速であることがわかりました。私のベンチマークコードが正しくないのでしょうか?

Intersect、ネストされたループ、および IndexOf を使用したループの間の 1 秒あたりの反復回数を見つけるために使用したコードを次に示します。VBを許してください。;)

Dim ArrayLength As Integer = 50
Dim doesContain As Boolean = False
Dim counter As Integer = 0
Dim sw As New System.Diagnostics.Stopwatch()
Dim BigArray1 As String() = New String(ArrayLength) {}
Dim BigArray2 As String() = New String(ArrayLength) {}
Dim rand As New Random(DateTime.Now.Millisecond)
For i As Integer = 0 To ArrayLength
    BigArray1(i) = Convert.ToChar(rand.Next(0, 255)).ToString()
    BigArray2(i) = Convert.ToChar(rand.Next(0, 255)).ToString()
Next
Dim AnEnumerable1 As IEnumerable(Of String) = BigArray1
Dim AnEnumerable2 As IEnumerable(Of String) = BigArray2

counter = 0
sw.Restart()
Do
    doesContain = False
    For Each x As String In AnEnumerable1
        For Each y As String In AnEnumerable2
            If x.Equals(y) Then
                doesContain = True
                Exit For
            End If
        Next
        If doesContain Then Exit For
    Next
    counter += 1
Loop While sw.ElapsedMilliseconds < 1000
Console.WriteLine("InnerLoop iterated:  " & counter.ToString() & " times in " & sw.ElapsedMilliseconds.ToString() & "ms.")

counter = 0
sw.Restart()
Do
    doesContain = AnEnumerable1.Intersect(AnEnumerable2).Any()
    counter += 1
Loop While sw.ElapsedMilliseconds < 1000
Console.WriteLine("Intersect iterated:  " & counter.ToString() & " times in " & sw.ElapsedMilliseconds.ToString() & "ms.")

counter = 0
sw.Restart()
Do
    For Each x As String In AnEnumerable1
        If Array.IndexOf(Of String)(BigArray2, x) <> -1 Then
            Exit For
        End If
    Next
    counter += 1
Loop While sw.ElapsedMilliseconds < 1000
Console.WriteLine("IndexOf iterated:    " & counter.ToString() & " times in " & sw.ElapsedMilliseconds.ToString() & "ms.")

私の結果は、2 つの 5,000,000 項目配列を超えています。反復回数が多いほど良い:

  • InnerLoop の反復: 1000 ミリ秒で 2974553 回。
  • 交差反復: 1168ms で 4 回。
  • IndexOf 反復: 1000 ミリ秒で 4194423 回。

私の結果は、2 つの 50 項目配列を超えています。反復回数が多いほど良い:

  • InnerLoop の反復回数: 1000 ミリ秒で 375712 回。
  • 交差反復: 1000 ミリ秒で 203721 回。
  • IndexOf 反復: 1000 ミリ秒で 668421 回。
于 2010-11-17T17:10:09.237 に答える