the*_*ser 29 c# algorithm performance
目前我有一list百万integers,我在每个integer2000 integer秒的黑名单中检查.这大约需要2分钟.
for(int i = 0; i< MillionIntegerList.Length ; i++)
{
for(int blacklisted = 0; blacklisted < TwoThousandIntegerList.Length ; blacklisted++)
if(i==blacklisted)
i = 0; //Zero is a sentinel value
}
Run Code Online (Sandbox Code Playgroud)
这样就可以完成2,000,000,000次迭代(循环).有没有更好的方式我没有看到?谢谢
Jon*_*eet 50
现在有三个选项 - 前两个更通用,因为它们不依赖于MillionIntegerList排序(最初未指定).在已经对大列表进行排序的情况下,第三个是优选的.
选项1
是的,使用LINQ肯定有更好的方法:
var common = MillionIntegerList.Intersect(TwoThousandIntegerList).ToList();
Run Code Online (Sandbox Code Playgroud)
那将在内部使用一个HashSet<int>内置的TwoThousandIntegerList,然后查找其中的每个元素MillionIntegerList- 这将比TwoThousandIntegerList每次完成整个过程更有效.
如果您只想要非黑名单的,您需要:
var valid = MillionIntegerList.Except(TwoThousandIntegerList).ToList();
Run Code Online (Sandbox Code Playgroud)
请注意,如果您只需要迭代结果一次,则应该删除该ToList调用 - 我已将其包含在内以实现结果,以便可以便宜地多次检查它们.如果你只是迭代,返回值Intersect或Except将只是流式传输结果,使其在内存使用方面更便宜.
选项2
如果您不想依赖LINQ to Objects的实现细节,但仍需要基于散列的方法:
var hashSet = new HashSet<int>(TwoThousandIntegerList);
hashSet.IntersectWith(MillionIntegerList);
// Now use hashSet
Run Code Online (Sandbox Code Playgroud)
选项3
使用大型列表排序这一事实的方法肯定是有用的.
假设您不介意首先排序列入黑名单的列表,您可以编写像这样的流式(和通用)实现(未经测试):
// Note: to use this, you'd need to make sure that *both* sequences are sorted.
// You could either sort TwoThousandIntegerList in place, or use LINQ's OrderBy
// method.
public IEnumerable<T> SortedIntersect<T>(this IEnumerable<T> first,
IEnumerable<T> second) where T : IComparable<T>
{
using (var firstIterator = first.GetEnumerator())
{
if (!firstIterator.MoveNext())
{
yield break;
}
using (var secondIterator = second.GetEnumerator())
{
if (!secondIterator.MoveNext())
{
yield break;
}
T firstValue = firstIterator.Current;
T secondValue = secondIterator.Current;
while (true)
{
int comparison = firstValue.CompareTo(secondValue);
if (comparison == 0) // firstValue == secondValue
{
yield return firstValue;
}
else if (comparison < 0) // firstValue < secondValue
{
if (!firstIterator.MoveNext())
{
yield break;
}
firstValue = firstIterator.Current;
}
else // firstValue > secondValue
{
if (!secondIterator.MoveNext())
{
yield break;
}
secondValue = secondIterator.Current;
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
(IComparer<T>如果你想要的话,你可以选择一个,而不是依赖于T的可比性.)
小智 5
在我看来,你需要的是Enumerable.Except方法(IEnumerable,IEnumerable)
点击这里http://msdn.microsoft.com/en-us/library/bb300779.aspx
| 归档时间: |
|
| 查看次数: |
2773 次 |
| 最近记录: |