使用SubList <t>性能(LINQ或不是)</t> </t>更新List <t>

时间:2014-01-06 12:56:25

标签: c# linq list generics updates

我有一个列表,可以有~200'000项。我需要使用子列表更新固定数量的字段,例如150项。这是我现在使用的代码:

listItem:200'000 item List - subListItem:150 item List(updated)

listItem.Select(item =>
{
    if (subListItem.Exists(x => x.ID == item.ID))
    {
        var currentItem = subListItem.Single(x => x.ID == item.ID);
        item.FIELD_1 = currentItem.FIELD_1;
        item.FIELD_2 = currentItem.FIELD_2;
        item.FIELD_3 = currentItem.FIELD_3;
        item.FIELD_4 = currentItem.FIELD_4;
    }

    return item;
}).ToList();

这很好用,但性能真的很差。你有什么建议吗?

更新的解决方案:

dictItem = listItem.ToDictionary(x => x.ID);

foreach (Item updatedItem in subListItem)
{
    Item originalItem = dictItem[updatedItem.ID];
    originalItem.FIELD_1 = updatedItem.FIELD_1;
    originalItem.FIELD_2 = updatedItem.FIELD_2;
    originalItem.FIELD_3 = updatedItem.FIELD_3;
    originalItem.FIELD_4 = updatedItem.FIELD_4;
    dictItem[updatedItem.ID] = originalItem;
}

3 个答案:

答案 0 :(得分:5)

利用字典使项目查找更快,即

var subListItemsById = subListItems.ToDictionary(x => x.ID);
foreach(var item in listItem)
{
    SubListItem subListItem;
    if(subListItemsById.TryGetValue(item.ID, out subListItem))
    {
        item.FIELD_1 = subListItem.FIELD_1;
        item.FIELD_2 = subListItem.FIELD_2;
        item.FIELD_3 = subListItem.FIELD_3;
        item.FIELD_4 = subListItem.FIELD_4;
    }
}

您的原始listItem将包含已修改的对象。这仅在listItem中包含的项目是引用类型时才有效。如果它们是可变结构,则需要与您的示例类似:

var subListItemsById = subListItems.ToDictionary(x => x.ID);
var modifiedItems =  listItem.Select(item =>
{
    SubListItem subListItem;
    if(subListItemsById.TryGetValue(item.ID, out subListItem))
    {
        item.FIELD_1 = subListItem.FIELD_1;
        item.FIELD_2 = subListItem.FIELD_2;
        item.FIELD_3 = subListItem.FIELD_3;
        item.FIELD_4 = subListItem.FIELD_4;
    }
    return item;
}).ToList();

答案 1 :(得分:2)

如果您需要更好的性能,则需要使用针对查找进行了优化的容器。例如,Dictionary使用您的ID作为密钥。

答案 2 :(得分:1)

通过创建所述的字典,您可以加快速度。但是,如果您不必创建副本,则可以保留原始列表,从而减少内存占用。

var subItemLookup = subItems.ToDictionary(i => i.Id);

foreach (var item in items)
{
    SubItem subItem;
    if (subItemLookup.TryGetValue(item.Id, out subItem))
    {
        item.Field1 = subItem.Field1;
        //etc.
    }
}