优化两个非常大的列表

时间:2016-12-16 15:14:30

标签: c# list loops optimization .net-core

在您阅读我的解释之前,我想告诉您,我需要优化处理时间来比较两个巨大的c#列表,在嵌套循环中逐个索引。提前感谢您详细阅读我的问题。

它是我用C#ofcourse创建的.Net核心应用程序。

在我的算法中,我必须创建一个包含一些整数范围的很长列表,如下所示。

internal class Global
{
    public string ChromosomeName { get; set; }
    public int start { get; set; }
    public int end { get; set; }
    public string Cluster { get; set; }
    public string Data { get; set; }
} 
var globals = new List<Global>();// somewhere in my method.

现在这个列表非常庞大,例如它会像这样存储值。这是我的主要列表,因此命名为&#39;全局&#39;

index 0 = start=1, end=400 ....
index 1 = start=401, end=800....
index (last) = start= 45090000 , end= 45090400 ...

这些只是粗略的估计值,所以你知道它会成为一个巨大的列表。

现在在我的算法中,我实际需要做的是

  • 所以我拿了一个文本文件,读取该文件并将其数据存储在另一个列表中,并且具有与上面代码中所示相同的属性。
  • 现在我有2个列表,全局列表和我从文件中读取的其他列表。
  • 这两个都是非常庞大的名单
  • 现在我必须在嵌套循环中逐个索引地比较它们。
  • 外循环将迭代我的全局列表,内循环将迭代我的另一个列表(我从文件中读取)。
  • 在我完成嵌套循环一次后,我读取了另一个文件并创建了另一个列表,然后以相同的方式将该列表与全局列表进行比较..
  • 因此,将会有一个全局列表,它将在嵌套循环中逐个索引地与大约10个列表进行比较,并且所有这些列表几乎与全局列表本身一样大。

下面是针对嵌套的foreach循环显示的psedocode。

foreach(var item in globals)
{
    var value=0;
    foreach(var item2 in otherHugeList)
    {
        compareMethod(item,item2);
        //below is the actual code of wht kind of comparison I am doing,     just if i guyx want to know, I am actually finding the overlap between two ranges.
       //value += Math.Max(0, Math.Min(range1.end, EndList[i]) -  Math.Max(range1.start, StartList[i]) + 1);
    }
}

现在请以最快的方式向我推荐这个,因为现在需要花费超过几个小时而且我感到很沮丧,我取消了这个过程,因为我不知道要花多长时间。所以我甚至无法在较小的文件上得到我的结果。

我需要知道最快的方法,我应该使用任何兼容.Net核心的库吗?或多线程以某种方式?我对线程概念不太了解。

P.S:我使用了Parallel.ForEach,它在性能上的差异可以忽略不计。

1 个答案:

答案 0 :(得分:6)

如果你需要逐个元素地比较每个10个 6 项目的两个列表,那么你需要进行10次 12 比较。它让你没有希望在一段时间内完成,所以解决这个问题的关键是大幅度减少比较次数。

进行缩小的确切方法取决于您正在运行的比较类型,所以让我们使用帖子中的重叠计算作为示例。

您知道当下面的一个陈述为真时,范围R和Q之间没有重叠:

  • R的上限低于Q的下限,或
  • R的下限高于Q的上限。

如果您的范围以随机顺序显示在列表中,则无效。但是,如果您在下限上对范围进行排序,并按上限解析关联,则可以使用二分搜索来查找您比较的每个范围的列表的相关部分,即重叠的元素。可能的。

假设同一列表中的范围之间几乎没有重叠,这将减少从每个元素大约一百万到每个元素一百以下的比较次数,从而使性能提高1000倍。

  

我的所有列表都没有自我重叠的范围(评论)

然后,您可以通过对两个范围列表进行排序,然后在单个循环中迭代它们来使用merge algorithm的变体。将索引设置为两个数组为零,然后一次一步地遍历两个列表。如果全局列表上的当前范围低于比较列表中当前范围的start级别,请转到全局列表的下一个元素;否则,转到比较列表的下一个元素。这两个索引将相互“追逐”,直到你以2M的增量到达两个列表的末尾。