我需要在列表项上测试的匹配条件非常耗时。而且,我知道条件将匹配不超过3项列表。
因此,检查所有列表项目可能不是最好的主意;但是,当我尝试最多使用FindFindex()
方法3次时,测试所用的时间比我使用FindAll()
和Where()
的情况要多。
如何加快此方法的速度,或者最快找到三场比赛?
| # Method Time (sec)
| -------------------------------
| 1 Find (one-by-one) 42.37
| 2 FindAll 30.17
| 3 Where 30.53
方法#1:
{
int index;
Predicate<T> predicate = t =>
{
...
};
index = myCollection.FindIndex(predicate);
if (index != -1)
{
T t1 = myCollection[index];
myCollection.RemoveAt(index);
index = myCollection.FindIndex(predicate);
if (index != -1)
{
T t2 = myCollection[index];
myCollection.RemoveAt(index);
index = myCollection.FindIndex(predicate);
if (index != -1)
{
T t3 = myCollection[index];
return new T[] { t1, t2, t3 };
}
else
{
return new T[] { t1, t2 };
}
}
else
{
return new T[] { t1 };
}
}
else
{
return new T[] { };
}
}
方法#2:
{
return myCollection.FindAll(t =>
{
...
}).ToArray();
}
方法#3:
{
return myCollection.Where(t =>
{
...
}).ToArray();
}
编辑: 修改方法#1:
{
int index;
Predicate<T> predicate = t =>
{
...
};
index = myCollection.FindIndex(predicate);
if (index != -1)
{
T t1 = myCollection[index];
index = myCollection.FindIndex(index + 1, predicate);
if (index != -1)
{
T t2 = myCollection[index];
index = myCollection.FindIndex(index + 1, predicate);
if (index != -1)
{
T t3 = myCollection[index];
return new T[] { t1, t2, t3 };
}
else
{
return new T[] { t1, t2 };
}
}
else
{
return new T[] { t1 };
}
}
else
{
return new T[] { };
}
}
答案 0 :(得分:6)
你的方式较慢,因为它遍历整个集合三次,并且因为你执行删除操作也会受到惩罚(“O(n),其中n是(Count - index)” ,according to MSDN)。
您可以通过调用FindIndex(int, predicate)
重载来避开这两种情况,int
在迭代源集合时谴责起始位置。
因此,请更换发生这种情况的地方:
myCollection.RemoveAt(index);
index = myCollection.FindIndex(predicate);
有了这个:
index = myCollection.FindIndex(index + 1, predicate)
答案 1 :(得分:2)
只要使用了List,就没有办法,只能迭代集合。您可以修改#3,如下所示:
return myCollection.Where(...).Take(3).ToArray();
ToArray将开始迭代,并且3将限制迭代在3个结果后停止。对于#1(修改过的)示例,这几乎是一回事。
编辑:
以下是关于Take&#39的Linqpad测试程序:
void Main()
{
var list = new List<Something>();
for(int i=0; i<100; i++)
list.Add(new Something { Value = i });
var result = list.Where(p => p.Value < 50).Take(3);
result.Count().Dump();
}
public class Something
{
private int _value;
public int Value
{
get { _value.Dump(); return _value; }
set { _value = value; }
}
}
测试结果:
0
1
2
3
最后一个是集合计数,只列举了3个项目。