【问题标题】:LINQ, Where() vs FindAll()LINQ,Where() 与 FindAll()
【发布时间】:2009-12-21 04:35:30
【问题描述】:

谁能解释一下 LINQ 函数 Where(..) 和 FindAll(..) 有何不同?他们似乎都在做同样的事情......

【问题讨论】:

标签: c# linq syntax


【解决方案1】:

FindAll()List<T> 类型的函数,它不是像Where 这样的LINQ 扩展方法。 LINQ 扩展方法适用于实现IEnumerable 的任何类型,而FindAll 只能用于List<T> 实例(当然,或者从它继承的类的实例)。

此外,它们的实际用途不同。 Where 返回IEnumerable 的实例,在枚举对象时按需执行。 FindAll 返回一个新的 List<T>,其中包含请求的元素。 FindAll 更像是在 IEnumerable 的实例上调用 Where(...).ToList()

【讨论】:

  • 是的,findall 的懒惰版在哪里
  • code.msdn.microsoft.com/LINQ-Query-Execution-ce0d3b95 解释了惰性(延迟)和立即执行之间的区别。基本上,在某些情况下,您不需要整个列表,您可能希望遍历项目直到发生某些事情,然后停止。这是延迟派上用场的地方,但根据实现,可能会导致不可预测的结果(所有内容都在链接中解释)。希望这会有所帮助。
【解决方案2】:

对我来说最大的不同是 .FindAll 在 .Net 2.0 中也可用。我并不总是有幸在 .Net 3.5 中编程,所以我尽量记住 .Net 泛型集合的“本机”方法。

有好几次我自己实现了一个已经可用的 List 方法,因为我无法对其进行 LINQ。

在这种情况下我觉得很方便的是,使用 VS2008,我可以使用类型推断和 lambda 语法。这些是编译器功能,而不是框架功能。这意味着我可以写这个并且仍然保留在 .Net 2.0 中:

var myOddNums = myNums.FindAll(n => n%2==1);

但是,如果您确实有可用的 LINQ,那么保持延迟执行和立即执行之间的区别很重要。

【讨论】:

    【解决方案3】:

    如果我没记错的话,主要区别(除了它们的实现方式:IEnumerable<T>List<T>)是Where 实现了延迟执行,在您需要之前它实际上不会进行查找它——例如在 foreach 循环中使用它。 FindAll 是立即执行方法。

    【讨论】:

      【解决方案4】:

      我对 80K 个对象的列表进行了一些测试,发现 Find() 可以比使用 WhereFirstOrDefault() 快 1000%。直到在每次通话之前和之后测试一个计时器,我才知道这一点。有时它是同一时间,有时它更快。

      【讨论】:

      • 您是否也尝试访问该集合? Enumerable.Where() 使用延迟执行并且在访问集合之前不会被评估,这可能会导致错误的概念,即它是否真的更快。尽管如此,在大多数情况下,使用可枚举而不是静态集合(如 Type 和 Array)通常更快。
      • 问题是关于 FindAll 的。很明显 Find 将比 Where (获取所有值)并获得 FirstOrDefault
      • 你试过 FirstOrDefault() 和 FIndAll() 吗?
      • 使用 Where 或 FindAll 与 .Count() 函数具有几乎相同的性能,但当 FindAll 使用 Length 属性而不是 Count() 时存在巨大差异,因此 FindAll 更适合搜索和过滤数组。
      【解决方案5】:

      性能方面FindAll() 更好,下面是一个示例。 FindAll 需要 3 毫秒,而 Where 需要 11 毫秒

          public class SortedSearch
          {
              public static int[] CountNumbersUsingFindAll(int[] sortedArray, int lessThan)
              {
                  var smaller = Array.FindAll(sortedArray,x => x < lessThan);
                  return smaller;
              }
              public static IEnumerable<int> CountNumbersUsingWhere(int[] sortedArray,int lessThan)
              {
                  var smaller = sortedArray.Where(x => x < lessThan);
                  return smaller;
              }
         }
      
      class Program
      {
              static void Main(string[] args)
              {
                  Stopwatch s = Stopwatch.StartNew();
                  Console.WriteLine(SortedSearch.CountNumbersUsingFindAll(new int[]{1,3,5,7},4));
                  Console.WriteLine(s.ElapsedMilliseconds);
                  s.Stop();
      
                  s.Restart();
                  Console.WriteLine(SortedSearch.CountNumbersUsingWhere(new int[] { 1, 3, 5, 7 }, 4));
                  Console.WriteLine(s.ElapsedMilliseconds);
                  s.Stop();
                  Console.ReadKey();
              }
      }
      

      【讨论】:

      • 您处于什么样的环境中,通过 4 个整数数组运行的方法需要接近 3 秒,更不用说 11 秒?这些结果有些不对劲。它们似乎相差了多个数量级。是 3 毫秒还是 11 毫秒?如果是这样的话,我建议不要在计时中包含 WriteLine 语句。
      • 实际上是毫秒而不是秒
      猜你喜欢
      • 1970-01-01
      • 2011-05-07
      • 2023-02-11
      • 2016-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-16
      • 1970-01-01
      相关资源
      最近更新 更多