【问题标题】:Compare two lists that contain a lot of objects比较两个包含大量对象的列表
【发布时间】:2011-05-15 10:44:12
【问题描述】:

我需要比较两个列表,每个列表包含大约 60,000 个对象。这样做最有效的方法是什么?我想选择源列表中不存在于目标列表中的所有项目。

我正在创建一个同步应用程序,其中 c# 扫描一个目录并将每个文件的属性放在一个列表中。因此有一个源目录列表和另一个目标目录列表。然后我不会复制所有文件,而是比较列表并查看哪些不同。如果两个列表都有相同的文件,那么我不会复制该文件。这是我使用的 Linq 查询,它在我扫描小文件夹时有效,但在扫描大文件夹时无效。

// s.linst is the list of the source files
// d.list is the list of the files contained in the destination folder
  var q = from a in s.lstFiles
        from b in d.lstFiles
        where
        a.compareName == b.compareName &&
        a.size == b.size &&
        a.dateCreated == b.dateCreated
        select a;

// create a list to hold the items that are the same later select the outer join
List<Classes.MyPathInfo.MyFile> tempList = new List<Classes.MyPathInfo.MyFile>();

foreach (Classes.MyPathInfo.MyFile file in q)
{
    tempList.Add(file);
}

我不知道为什么这个查询需要永远。还有其他我可以利用的东西。例如,我知道如果源文件与目标文件匹配,则不可能与该文件有另一个副本,因为不可能有相同名称和相同路径的文件名。

【问题讨论】:

    标签: c# linq performance


    【解决方案1】:

    为该类型创建一个相等比较器,然后您可以使用它来有效地比较集合:

    public class MyFileComparer : IEqualityComparer<MyFile> {
    
      public bool Equals(MyFile a, MyFile b) {
        return
          a.compareName == b.compareName &&
          a.size == b.size &&
          a.dateCreated == b.dateCreated;
      }
    
      public int GetHashCode(MyFile a) {
        return
         (a.compareName.GetHashCode() * 251 + a.size.GetHashCode()) * 251 +
          a.dateCreated.GetHashCode();
      }
    
    }
    

    现在您可以将其与 Intersect 等方法一起使用,以获取两个列表中都存在的所有项目,或 Except 以获取一个列表中存在但另一个列表中不存在的所有项目:

    List<MyFile> tempList =
      s.lstFiles.Intersect(d.lstFiles, new MyFileComparer()).ToList();
    

    由于这些方法可以使用哈希码将项目划分为桶,因此与必须将一个列表中的所有项目与另一个列表中的所有项目进行比较的连接相比,需要进行的比较要少得多.

    【讨论】:

      【解决方案2】:

      LINQ 有一个 Except() 用于此目的的方法。你可以使用a.Except(b);

      【讨论】:

        【解决方案3】:

        使用Except() 并阅读有关set operations with linqset operations with HashSet 的更多信息。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-01-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-02-08
          相关资源
          最近更新 更多