C# 在c中比较一百万个对象列表和另外一百万个对象列表的最佳方法#

C# 在c中比较一百万个对象列表和另外一百万个对象列表的最佳方法#,c#,asp.net-mvc,linq,for-loop,foreach,C#,Asp.net Mvc,Linq,For Loop,Foreach,我正在区分一百万个对象列表和另外一百万个对象列表。 我正在使用for、foreach,但迭代这些列表需要花费太多时间。 有人能帮我找到最好的方法吗 var SourceList = new List<object>(); //one million var TargetList = new List<object>()); // one million //getting data from database here //SourceList with List o

我正在区分一百万个对象列表和另外一百万个对象列表。 我正在使用for、foreach,但迭代这些列表需要花费太多时间。 有人能帮我找到最好的方法吗

var SourceList = new List<object>(); //one million 
var TargetList = new List<object>()); // one million

//getting data from database here
//SourceList with List of one million 
//TargetList with List of one million

var DifferentList = new List<object>();

//ForEach
SourceList.ToList().ForEach(m =>
    {
      if (!TargetList.Any(s => s.Name == m.Name))
            DifferentList.Add(m);
  });

 //for
 for (int i = 0; i < SourceList .Count; i++)
   {
    if (!TargetList .Any(s => s == SourceList [i].Name))
            DifferentList .Add(SourceList [i]);
  }



var SourceList=newlist()//一百万
var TargetList=new List());//一百万
//在这里从数据库获取数据
//SourceList的列表为一百万
//100万人的目标列表
var differentitlist=新列表();
//弗雷奇
SourceList.ToList().ForEach(m=>
{
如果(!TargetList.Any(s=>s.Name==m.Name))
差异列表。添加(m);
});
//为了
for(int i=0;is==SourceList[i].Name))
differentilist.Add(SourceList[i]);
}

Foreach在每次迭代之前都执行空检查,因此使用标准for循环将提供稍好的性能,这是很难打败的

如果花费的时间太长,您能否将集合分解为更小的集合和/或并行处理它们

您还可以使用
.aspallel()

其他需要改进的方面是您正在使用的实际比较逻辑,以及数据在内存中的存储方式,根据您的问题,您可能不必为每次迭代将整个对象加载到内存中

请提供一个代码示例,以便我们在涉及如此大量的数据时提供进一步的帮助。预计性能会下降


同样,根据我们在这里讨论的时间,您可以将数据上传到数据库中,并将其用于比较,而不是尝试在C#中进行本机比较,这种类型的解决方案更适合于数据库中已经存在的数据集,或者数据更改的频率远远低于执行比较所需的时间。

扫描目标列表以匹配名称是一种O(n)操作,因此循环是O(n^2)。如果构建目标列表中所有不同名称的
HashSet
,则可以使用Contains方法在O(1)时间内检查集合中是否存在名称

//在这里从数据库获取数据

您将数据从一个专门进行数据匹配、排序和过滤的系统中取出,放入RAM中,默认情况下,RAM根本无法完成该任务。然后你试着自己排序、过滤和匹配

这将失败。不管你怎么努力,你的计算机如果只有一个程序员在一个匹配的算法上工作,就不太可能在一个被称为数据库服务器的特殊硬件上表现得比你的计算机更好。这个软件应该非常擅长于一个由专家团队编写并经过多年优化的操作

你不会走进一家高档餐厅,让他们给你一大袋原料,这样你就可以把它们扔进一个大碗里,不用剥皮,在家里用微波炉加热。不,你点了一道好菜,因为它比你自己做的任何菜都好


简单的答案是:不要那样做。不要拿着原始数据在里面翻找几个小时。把那个工作留给数据库。这是它应该擅长的一件事。使用它的力量。写一个能给出结果的查询,不要获取原始数据,然后自己玩数据库。

我认为这似乎是个坏主意,但IEnumerable magic会帮你

首先,简化您的表达式。看起来是这样的:

var result = sourceList.Where(s => targetList.Any(t => t.Equals(s)));
var cnt = result.Count();
我建议使用
Equals
方法进行比较:

public class CompareObject
{
    public string prop { get; set; }

    public new bool Equals(object o)
    {
        if (o.GetType() == typeof(CompareObject))
            return this.prop == ((CompareObject)o).prop;    
        return this.GetHashCode() == o.GetHashCode();
    }
}    
下一步添加
aspallel
。这可以加快和减慢您的程序。在您的情况下,您可以添加

var result = sourceList.AsParallel().Where(s => !targetList.Any(t => t.Equals(s)));
如果您尝试一次列出所有CPU,则CPU 100%已加载,如下所示:

var result = sourceList.Where(s => targetList.Any(t => t.Equals(s)));
var cnt = result.Count();
但是,如果你只得到一小部分的结果,那么这是可以容忍的

result.Skip(10000).Take(10000).ToList();
完整代码:

static Random random = new Random();
public class CompareObject
{
    public string prop { get; private set; }

    public CompareObject()
    {
        prop = random.Next(0, 100000).ToString();
    }

    public new bool Equals(object o)
    {
        if (o.GetType() == typeof(CompareObject))
            return this.prop == ((CompareObject)o).prop;    
        return this.GetHashCode() == o.GetHashCode();
    }
}

void Main()
{
    var sourceList = new List<CompareObject>();
    var targetList = new List<CompareObject>();
    for (int i = 0; i < 10000000; i++)
    {
        sourceList.Add(new CompareObject());
        targetList.Add(new CompareObject());
    }

    var stopWatch = new Stopwatch();

    stopWatch.Start();
    var result = sourceList.AsParallel().Where(s => !targetList.Any(t => t.Equals(s)));


    var lr = result.Skip(10000).Take(10000).ToList();
    stopWatch.Stop();

    Console.WriteLine(stopWatch.Elapsed);
}

发布一些代码。这会很有帮助。首先,这不是一个C#问题,而是一个一般性问题。根据您的结构,您可以使用排序列表或二叉树…比较对象的基础是什么?您可以将列表拆分为更小的块并并行运行您的操作吗?在询问堆栈溢出问题时,有一个建议:响应,参与!如有必要,回复您收到的答案,以便回答者知道他们在正确的轨道上,并始终在评论中回复问题或建议。在某些情况下(如MVVM)您可能只处理模型对象,甚至不访问数据库。MVVM中没有规定您必须通过不使用数据库来故意破坏您的程序。您可以在模型中使用一个方法来查询数据库并返回结果列表。