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

问题描述:

我必须能够列出可能包含具有特定标准的doubloon的对象列表。到目前为止,代码正在工作,但是我的列表中有50,000行需要10分钟。我可以做些什么来优化我的linq查询吗?

下面是代码:

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; 
    } 

的想法是每个所以我的LINQ的要求是最小的名单可能在执行我通过while循环时间缩短列表。然而,我拥有的金币越少,速度就越慢。我正在寻找一种解决方案,使我可以拥有最小的rutnime,内存不是问题。

有没有人有想法?

+0

杜布隆=双重元素,你想要做的事,当你遇到这种情况? – Femaref 2011-03-16 17:58:38

+2

我闻到copypasta错误:你确定将value3与value4比较? (currentElement.Value.value3 == originalElement.value4) – 2011-03-16 18:02:38

+0

A doubloon是一枚金币。我不明白与这个问题有什么关系。 – Gabe 2011-03-16 18:02:51

我试图通过你的代码 - 它看起来像你只是想从你的源列表中删除重复?

如果是这样的话:

  • 那么我认为你的source.RemoveAt代码可能会被打破,因为它可能会删除错误的元素。

  • 那么你应该能够在这个源列表上运行一个单独的GroupBy()操作 - 应该使用一个散列表,它应该比现有的循环内部循环操作快得多。

    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(); 
    
+1

由于聚合结果的附加要求,“不同”将不起作用。 – Femaref 2011-03-16 18:13:40

+0

同意 - 我已经解决了这个问题,并且改变了答案 - 但为时已晚......你已经击败了我!我会鼓励你的... – Stuart 2011-03-16 18:19:00

+0

由于我存储了我从查询中得到的源代码索引,所以我确信每个索引都是正确的。我在小列表上测试了我的代码。虽然我可能在粘贴时犯了错误。你能告诉我哪个部分是问题吗?我会试试这个,谢谢! – lollancf37 2011-03-16 22:47:47

如果我正确理解你的问题,你有多个元素具有相同的密钥,并希望在这种情况下做一些事情。只是使用一组声明:

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) 
        }); 
+0

谢谢。就您的代码和@Stuart之间的性能而言,您的看法有差异。我在问,因为我从来没有真正区别从IEnumerable对象调用操作符或使用Linq语法。我希望自己清楚O_o – lollancf37 2011-03-16 22:55:35

+0

不,完全没有区别 - Stuart的代码只是一种用更像sql语法编写我的代码的方法(它实际上应该翻译成我的代码)。查询语法是以更可读的方式表达复杂查询的一种方式,但是它可以在LINQ中使用所有可能的功能。 – Femaref 2011-03-16 22:58:13

+0

好吧,这真的是一个味道的问题。谢谢。主要是, – lollancf37 2011-03-17 10:04:38