繁体   English   中英

具有位置的大型有序集合的C#数据类型?

[英]C# Datatype for large sorted collection with position?

我试图比较SQL查询中的两个大数据集。 现在,SQL查询是在外部完成的,每个数据集的结果都保存在自己的csv文件中。 我的小C#控制台应用程序加载两个text / csv文件,并将它们与差异进行比较,并将差异保存到文本文件中。

它是一个非常简单的应用程序,它只是将第一个文件中的所有数据加载到arraylist中,并在arraylist上执行.compare(),因为每行都是从第二个csv文件中读取的。 然后保存不匹配的记录。

该应用程序有效,但我想提高性能。 我想我可以大大提高性能,如果我可以利用两个文件都已排序的事实,但我不知道C#中保持顺序的数据类型,并允许我选择一个特定的位置。 这是一个基本数组,但我不知道每个列表中有多少项。 我可以有超过一百万条记录。 是否有可用的数据类型我应该查看?

如果两个CSV文件中的数据已经排序并且具有相同数量的记录,则可以完全跳过数据结构并进行就地分析。

StreamReader one = new StreamReader("C:\file1.csv");
StreamReader two = new StreamReader("C:\file2.csv");
String lineOne;
String lineTwo;

StreamWriter differences = new StreamWriter("Output.csv");
while (!one.EndOfStream)
{
    lineOne = one.ReadLine();
    lineTwo = two.ReadLine();
    // do your comparison.
    bool areDifferent = true;

    if (areDifferent)
        differences.WriteLine(lineOne + lineTwo);
}

one.Close();
two.Close();
differences.Close();

System.Collections.Specialized.StringCollection允许您添加一系列值,并使用.IndexOf(字符串)方法,允许您检索该项的索引。

话虽这么说,你可能只是从文件流加载几个byte []并进行字节比较......甚至不用担心将这些东西加载到像StringCollection或string []这样的正式数据结构中; 如果您所做的只是检查差异,并且您想要速度,我会想到字节差异就在它的位置。

这是David Sokol的代码改编,用于处理不同数量的行,输出一个文件而不是另一个文件中的行:

StreamReader one = new StreamReader("C:\file1.csv");
StreamReader two = new StreamReader("C:\file2.csv");
String lineOne;
String lineTwo;
StreamWriter differences = new StreamWriter("Output.csv");
lineOne = one.ReadLine();
lineTwo = two.ReadLine();
while (!one.EndOfStream || !two.EndOfStream)
{
  if(lineOne == lineTwo)
  {
    // lines match, read next line from each and continue
    lineOne = one.ReadLine();
    lineTwo = two.ReadLine();
    continue;
  }
  if(two.EndOfStream || lineOne < lineTwo)
  {
    differences.WriteLine(lineOne);
    lineOne = one.ReadLine();
  }
  if(one.EndOfStream || lineTwo < lineOne)
  {
    differences.WriteLine(lineTwo);
    lineTwo = two.ReadLine();
  }
}

关于代码写在我头顶的标准警告适用 - 你可能需要特殊情况下一行中没有行,而另一行仍然有行,但我认为这种基本方法应该做你想要的。

那么,有几种方法可行。 您可以编写自己的数据结构来执行此操作。 或者您可以尝试使用SortedList。 您还可以在代码中返回DataSet,然后在表上使用.Select()。 当然,您必须在两个表上执行此操作。

您可以轻松使用SortedList进行快速查找。 如果要加载的数据已经排序,则对SortedList的插入不应该很慢。

如果您只想查看FileA中的所有行是否都包含在FileB中,您可以读取它并仅比较循环内的流。

文件1 Entry1 Entry2 Entry3

文件2 Entry1 Entry3

您可以通过两个计数器循环查找遗漏,逐行浏览每个文件,看看是否得到了您需要的东西。

也许我误解了,但ArrayList将按照添加它们的顺序维护其元素。 这意味着您只能在一次通过中比较两个ArrayLists - 只需根据比较结果递增两个扫描索引。

我有一个问题是你考虑过“外包”你的比较。 有很多很好的差异工具,你可以呼吁。 如果没有一个允许你指定两个文件并且只获得差异,我会感到惊讶。 只是一个想法。

我认为每个人都有这么多不同答案的原因是你没有完全指出你的问题得到回答。 首先,它取决于您想要跟踪的差异。 您是否希望在WinDiff中输出差异,其中第一个文件是“原始”,第二个文件是“已修改”,因此您可以将更改列为INSERT,UPDATE或DELETE? 您是否有一个主键,允许您将两行匹配为同一记录的不同版本(当主键以外的字段不同时)? 或者这是某种和解,你只是希望你的差异输出说“记录在文件1而不是文件2”?

我认为这些问题的答案将帮助每个人为您的问题提供合适的答案。

如果你有两个文件,每个文件都是你的帖子中提到的一百万行,你可能会耗费大量内存。 某些性能问题可能是您正在从磁盘交换。 如果您只是将文件A的第1行与文件B,第2行文件A - >第2行文件B等的第一行进行比较,我建议使用一种不会在内存中存储太多的技术。 你可以读取两个文件流的注销,就像之前发布的评论者一样,并在你找到它们时“实时”写出你的结果。 这不会在内存中明确存储任何内容。 你也可以将每个文件的块转储到内存中,比如一次说一千行,就像List一样。 这可以很好地调整,以满足您的需求。

要解决问题#1,我建议您考虑创建每行的哈希值。 这样,您可以使用字典快速轻松地比较哈希。

要解决问题#2,一个快速而肮脏的解决方案是使用IDictionary。 使用itemId作为第一个字符串类型,将行的其余部分用作第二个字符串类型。 然后,您可以快速查找itemId是否存在并比较这些行。 这当然假设.Net 2.0+

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM