gpt4 book ai didi

LINQ 性能

转载 作者:行者123 更新时间:2023-12-03 18:28:06 26 4
gpt4 key购买 nike

在针对对象集合的 LINQ 查询的幕后究竟发生了什么?它只是语法糖还是发生了其他事情使其更有效的查询?

最佳答案

您是指查询表达式,还是查询在幕后的作用?

查询表达式首先扩展为“普通”C#。例如:

var query = from x in source
where x.Name == "Fred"
select x.Age;

被翻译成:
var query = source.Where(x => x.Name == "Fred")
.Select(x => x.Age);

这的确切含义取决于 source 的类型。当然...在 LINQ to Objects 中,它通常实现 IEnumerable<T>Enumerable扩展方法开始发挥作用......但它可能是一组不同的扩展方法。 (例如,LINQ to SQL 将使用 Queryable 扩展方法。)

现在,假设我们正在使用 LINQ to Objects... 扩展方法扩展后,上面的代码变为:
var query = Enumerable.Select(Enumerable.Where(source, x => x.Name == "Fred"),
x => x.Age);

接下来是 Select 的实现和 Where变得重要。忽略错误检查,它们是这样的:
public static IEnumerable<T> Where<T>(this IEnumerable<T> source,
Func<T, bool> predicate)
{
foreach (T element in source)
{
if (predicate(element))
{
yield return element;
}
}
}

public static IEnumerable<TResult> Select<TSource, TResult>
(this IEnumerable<TSource> source,
Func<TSource, TResult> selector)
{
foreach (TSource element in source)
{
yield return selector(element);
}
}

接下来是将迭代器 block 扩展为状态机,我不会在这里讨论,但我有一个 article about .

最后,将 lambda 表达式转换为额外的方法 + 适当的委托(delegate)实例创建(或表达式树,取决于所调用方法的签名)。

所以基本上 LINQ 使用了很多 C# 的巧妙特性:
  • Lambda 表达式转换(到委托(delegate)实例和表达式树)
  • 扩展方法
  • 泛型方法的类型推断
  • 迭代器 block
  • 通常是匿名类型(用于投影)
  • 局部变量的隐式类型
  • 查询表达式翻译

  • 然而,单个操作非常简单——它们不执行索引等。连接和分组是使用哈希表完成的,但是像“where”这样的简单查询只是线性的。不要忘记 LINQ to Objects 通常只是将数据视为只能向前读取的序列——它不能执行二进制搜索之类的操作。

    通常我希望手写查询比 LINQ to Objects 稍微快一点,因为抽象层更少,但它们的可读性会降低,而且性能差异通常不会很大。

    与以往一样,对于性能问题:如有疑问,请测量!

    关于LINQ 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1229838/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com