Это довольно интересно.
Документация для IEnumerable<T>.Contains
говорит, что если параметр источника реализует ICollection<T>
, то он вызывает ICollection<T>.Contains
. И поскольку string[]
реализует ICollection<string>
, это то, что называется.
Реализация Array
ICollection<T>.Contains
заканчивается вызовом Array.IndexOf
.
Если вы измените свой код на:
if (Array.IndexOf(symbol, "B"))
Он выполняется так же быстро, как и Any
. То же самое, если вы измените код на:
if ((symbol as ICollection<string>).Contains("B"))
В моих тестах вызов Array.IndexOf
в два раза быстрее вызова symbol.Contains
.
Я подозреваю, что все замедляется тем, что IEnumerable<T>.Contains
должен решать с каждым вызовом, будет ли он вызывать ICollection<T>.Contains
, или делать что-то еще. Это решение не нужно принимать, когда вызывается Any
.
Вы можете заменить весь код в IsWin
этим, который быстрее, чем любой из вышеперечисленных, и намного проще.
static bool IsWin(IList<string[]> slotView)
{
return slotView.Any(s => s[1] == "B");
}
Тогда, конечно, вы можете просто полностью избавиться от метода IsWin
и написать в своем внутреннем цикле:
if (slotView.Any(s => s[1] == "B")
++count;