我有一个方法Comparer,我比较了两个集合的对象的一些属性。
public IEnumerable<Product> Comparer(IEnumerable<Product> collection, IEnumerable<Product> target, string comparissonKey)
{
var count = 0;
var stopWatch = new Stopwatch();
var result = new ConcurrentBag<Product>();
var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount * 2 };
Parallel.ForEach(collection, parallelOptions, obj =>
{
count++;
if (count == 60000)
{
stopwatch.Stop();
//breakpoint
var aux = stopwatch.Elapsed;
}
var comparableObj = obj;
comparableObj.IsDifferent = false;
bool hasTargetObject = false;
comparableObj.Exist = true;
Product objTarget = null;
foreach (Product p in target)
{
if (obj.Key == p.Key)
{
objTarget = p;
break;
}
}
if (objTarget != null)
{
//Do stuff
}
if (hasTargetObject) return;
if (comparableObj.IsDifferent)
{
//Do Stuff
}
});
return result.ToList();
}
如果我像这样执行这个方法,我会在aux变量中断几乎50秒到断点。 如果我评论第二个foreach(在Parallel.Foreach内)它会在不到1秒的时间内中断。
我需要使用Key在目标集合中找到相应的对象,所以我做了第二个foreach。我使用LINQ where子句但没有得到更好的结果。有什么建议可以改善这种方法的表现吗?
答案 0 :(得分:1)
您可以使用字典来提高效果:
public IEnumerable<Product> Comparer(IEnumerable<Product> collection, IEnumerable<Product> target, string comparissonKey)
{
var count = 0;
var stopWatch = new Stopwatch();
var result = new ConcurrentBag<Product>();
var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount * 2 };
// create a dictionary for fast lookup
var targetDictionary = target.ToDictionary(p => p.Key);
Parallel.ForEach(collection, parallelOptions, obj =>
{
count++;
if (count == 60000)
{
stopwatch.Stop();
//breakpoint
var aux = stopwatch.Elapsed;
}
var comparableObj = obj;
comparableObj.IsDifferent = false;
bool hasTargetObject = false;
comparableObj.Exist = true;
Product objTarget = null;
// lookup using dictionary
if (targetDictionary.TryGetValue(obj.Key, out objTarget))
{
//Do stuff
}
if (hasTargetObject) return;
if (comparableObj.IsDifferent)
{
//Do Stuff
}
});
return result.ToList();
}
答案 1 :(得分:1)
如果Key确实是一个关键词 然后使用HashSet,因为它有IntersetWith并且正在快速吸烟 http://msdn.microsoft.com/en-us/library/bb359438.aspx
在您的类产品上,您需要覆盖GetHashCode和Equals
使用GetHashCode的密钥