将数据从一个列表复制到另一个列表需要很长时间

时间:2019-08-13 03:29:08

标签: c# linq

我有两个列表:{ "compilerOptions": { "baseUrl": ".", "outDir": "./dist/", "sourceMap": true, "noImplicitAny": true, "skipLibCheck": true, "module": "es2015", "target": "es5", "jsx": "react", "strictNullChecks": true, "allowJs": true, "declaration": false, "allowSyntheticDefaultImports": true, "moduleResolution": "node", "lib": [ "dom", "es2015", "es5", "es6" ] } } ~/.rstudio-desktop/sources/ ,它们每个都有两个共同的属性List A (is a Dictionary)。我正在尝试使用下面的linq代码将List1数据带入列表2,但这要花几乎9分钟的时间来执行循环(35k条记录)。请协助如何有效地将这两个列表数据读入一个列表,而不会出现性能问题。我已将C1和C2附加到单个属性C1C2。

  

列表A

     

C1 | C2 | desc_1 | desc_2 | DataType

     

0 | 1 | 0 | 1 | TEXT

     

0 | 2 | 0 | 2 | TEXT

     

0 | 3 | 0 | 3 | TEXT

     

0 | 4 | 0 | 4 | TEXT

     

22 | 1 | 22 | 1 |数字

     

22 | 2 | 22 | 2 |数字

  

列表B

     

App_Id | C1 | C2 |值

     

12 | 0 | 1 | 55R76

     

12 | 0 | 2 |测试记录

     

12 | 0 | 3 | CHOPPER

     

12 | 0 | 4 | TEST MD

     

13 | 0 | 1 | 9866FGG078

     

13 | 0 | 2 | TITLE2

     

13 | 22 | 1 |今天

     

13 | 22 | 2 | TEST12344

到目前为止,这是我的代码:

List B(Data)

预期结果:

  

App_Id,C1,C2,Desc1,Desc2,DataType和一个列表中的值。

2 个答案:

答案 0 :(得分:1)

您可以将ListB转换为字典-DicB,因此复杂度为 O(n)

var DicB = ListB.ToDictionary(x => x.C1C2, x => x);

foreach(var itemA in ListA)
{
    if(DicB.ContainsKey(itemA.C1C2))
    {
        var itemB = DicB[itemA.C1C2];
        itemB.Desc1 = itemA.Desc1;
        itemB.Desc2 = itemA.Desc2;
        itemB.DataType = itemA.DataType;
    }
}

答案 1 :(得分:-2)

您当前的实现是O(n ^ 2),随着数据大小的增加,它的确会变得非常慢。您实际上有两个嵌套循环:外部foreach,然后是FirstOrDefault()调用中的隐式循环(必须扫描ListB集合以找到感兴趣的元素)。

您已经在做join,但是由于某些原因没有习惯使用它。也就是说,通常当人们使用join查询时,他们实际上会进行 join 数据,以便可以在O(n)时间顺序枚举找到的配对元素。

在您的问题中缺少完整的代码示例,因此无法确定如何修复代码是不可能的,但是我希望这样会更好:

var query = from x in ListB
            join y in ListA
            on x.C1C2 equals y.C1C2
            select new { Source = y, Target = x };

//Update metadata from ListA to ListB
foreach (var x in query)
{
    x.Target.Desc1 = x.Source.Desc1;
    x.Target.Desc2 = x.Source.Desc2;
    x.Target.DataType = x.Source.DataType;
}