比较集合方法的性能

本文关键字:性能 方法 集合 比较 | 更新日期: 2023-09-27 17:50:54

我有一个比较方法,用来比较两个集合中对象的一些属性。

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();
}

如果我像这样执行这个方法,我得到几乎50秒的断点在aux变量中断。如果我注释第二个foreach(在Parallel.Foreach中),它将在不到1秒的时间内中断。

我需要使用Key在目标集合中找到相应的对象,因此我执行了第二个foreach。我使用LINQ where子句,但我没有得到更好的结果。对于改进这个方法的性能有什么建议吗?

比较集合方法的性能

您可以通过使用字典来提高性能:

    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();
    }

如果Key确实是Key
然后使用HashSet,因为它具有IntersetWith并且吸烟速度快
http://msdn.microsoft.com/en-us/library/bb359438.aspx

在你的Product类中,你需要重写GetHashCode和Equals
为GetHashCode使用Key

重写GetHashCode