我可以做些什么来优化我的linq查询?

时间:2011-03-16 17:54:07

标签: c# linq-to-objects

我必须能够根据某些标准整理出可能包含doubloon的对象列表。到目前为止,代码正在运行,但我的列表中需要10万分钟才能获得50,000行。

以下是代码:

    public class TestObject
    {
        public string value1;
        public string value2;
        public string value3;
        public string value4;

        public int num1;
        public int num2;
    }

    public static List<TestObject> ReturnTestObjectListWithoutDoubloon(List<TestObject> source)
    {
        var destination = new List<TestObject>();
        var list = new Dictionary<int, TestObject>();


        while (source.Count > 0)
        {
            list.Clear();
            var originalElement = source[0];

            foreach (var query in source.Select((element, index) => new { Value = element, Index = index })
            .Where(currentElement => (currentElement.Value.value1 == originalElement.value1)
                                    && (currentElement.Value.value2 == originalElement.value2)
                                    && (currentElement.Value.value3 == originalElement.value3)
                                    && (currentElement.Value.value4 == originalElement.value4)))
            {
                list.Add(query.Index, query.Value);
            }

            if (list.Count > 1)
            {
                originalElement.num1 = list.Sum(a => a.Value.num1);
                originalElement.num2 = list.Sum(a => a.Value.num2);
            }

            destination.Add(originalElement);
            foreach (var positionToremove in list.Keys)
                source.RemoveAt(positionToremove);
        }

        return destination;
    }

我的想法是每次传递while循环时减少列表,这样我的Linq请求就可以在最小的列表上执行。然而,我拥有的双倍数越少,它就越慢。我正在寻找一种解决方案,让我能够拥有最小的rutnime,记忆不是问题。

有没有人有想法?

2 个答案:

答案 0 :(得分:3)

如果我正确理解了您的问题,那么您有多个具有相同密钥的元素,并希望在这种情况下执行某些操作。只需使用group by语句:

source.GroupBy(s => new
                    {
                      Value1 = s.Value1,
                      Value2 = s.Value2,
                      Value3 = s.Value3,
                      Value4 = s.value4
                    })
      .Select(g => new TestObject
                   {
                      Value1 = g.Key.Value1,
                      Value2 = g.Key.Value2,
                      Value3 = g.Key.Value3,
                      Value4 = g.Key.value4,
                      Num1 = g.Sum(s => s.Num1),
                      Num2 = g.Sum(s => s.Num2)
                   });

答案 1 :(得分:1)

我尝试过关注您的代码 - 看起来您只是想从源列表中删除重复项?

如果是这种情况:

  • 然后我认为您的source.RemoveAt代码可能会被破坏,因为它可能会删除错误的元素。

  • 那么你应该能够在这个源列表上运行一个GroupBy()操作 - 这应该使用哈希表,它应该比现有的loop-inside-loops操作快得多。

    var query = from s in source
                group s by new {
                    value1 = s.value1,
                    value2 = s.value2,
                    value3 = s.value3,
                    value4 = s.value4
                } into grouped
                select new TestObject()
                {
                    value1 = grouped.Key.value1,
                    value2 = grouped.Key.value2,
                    value3 = grouped.Key.value3,
                    value4 = grouped.Key.value4,
                    num1 = grouped.Sum(x => x.num1),
                    num2 = grouped.Sum(x => x.num2)
                };
    return query.ToList();