使用C#

时间:2016-12-21 18:04:57

标签: c# excel

我写了一个小的C#程序,它比较了属于两个不同Excel工作表的两列。这些列中的每一列包含约23.000个细胞。对于第一列的每个元素,该过程检查元素的值是否存在于第二列中,如果它不存在,则从第一个工作表中删除该行。 问题是这个过程非常慢:扫描第二列需要大约10秒钟才能找到匹配值,因此程序执行大约需要10 * 23.000秒= 63小时。

在C#中有更快的方法吗?

3 个答案:

答案 0 :(得分:1)

这是一种可能解决此问题的方法。你说你有大约23,000行GUID,所以你应该能够加载HashSet和第2列中的所有GUID。然后你可以处理column1,获取你在HashSet中找到的每个元素。

var column2 = new HashSet<Guid>(); // Load this set with the data from column2

// Now you can just use a simple LINQ query to create a new column1
var column1Result = column1.Where(x => column2.Contains(x)).ToList();

现在您将拥有一个GUID列表,它们是您的新列1。只需用新的column1替换原始column1并保存文件。

在我的机器上进行测试,包括填充两个列表的时间和一个包含100,000 GUID的集合(我的测试列1有50,000个匹配和50,000个不匹配),整个过程大约需要0.15秒。

修改 - 根据您的评论 根据您描述的情况,我将解析工作表2以获取GUID并将所有这些内容放在HashSet中。然后我只需走下工作表2的第1列,检查HashSet中的包含情况,并根据需要删除。

答案 1 :(得分:0)

如果列中的值是double类型,则可以对它们进行排序。在每个搜索循环中,从最后一个循环开始最后一个位置,并在达到比您要查找的数字大的数字时停止搜索。

例如,您想在数组[1,3,4,5,6,7,9,10]中查找[2,4,7]。对于第一个循环,您要查找数字2,因此搜索范围为[1,3]。你停在3,因为3大于2.然后对于下一次搜索,你从3开始,到4结束,因为你找到了它。

答案 2 :(得分:0)

毫无疑问,有一百万种不同的方法可以做到这一点。使用Excel,您可能需要检查特定的挂起。其他人提到删除功能很慢,但也确保每次运行检查时都不会创建/处理对象。保留所有对象,只需更改所需的变量即可。您还可以考虑多线程并处理不同线程上的每一行。不要试试这个,除非你对你的多线程技能有信心......

尝试使用简单的基于排序的解决方案来缩短解析时间 -

  1. 对A行和B行进行排序。
  2. 将值存储在B的中间(单元格B.Count / 2的值)
  3. 迭代A - 首先检查值是否在B的上半部分或下半部分,然后仅搜索该列的一半。
  4. *确保在找到值之后中断处理,假设您的列表已经不同。