最近与同事的对话就此事产生了不同的观点。SO 成员们你们怎么说?

我知道,即使是可扩展性的概念也可以以多种不同的方式和背景来理解,但这就是这个问题出现时讨论的一部分。对于可扩展性的真正含义,每个人似乎都有不同的看法。我也很好奇这里有不同的看法。其实我发过一个 问题 只是为了这个概念。

有帮助吗?

解决方案

我猜想检查的最佳方法是编写基准测试,但在我看来,LINQ有可能优化手工编写类似的代码。我不知道它如何利用这些。

LINQ可让您表达您想要的内容,而不是如何生成它。一个明显的优点是LINQ可以自动并行化(参见 PLINQ )。

LINQ的另一个优点是它很懒,所以你可以根据需要从集合中进行计算。您可以手动编写等效的代码,但在LINQ中可能更容易实现。

其他提示

在测试中,LINQ to objects(ForEach)比foreach循环慢约2倍。

LINQ to SQL(MS SQL数据库)几乎 10x 比使用数据读取器的直接查询慢,使用大部分时间从表达式树创建SQL(所以,你将是CPU绑定和数据库将空转) 为避免这种情况,您必须使用已编译的查询。

有关详情,请参阅此。帖子中的大多数信息仍然适用于.NET 3.5 SP1。

这个问题有点像询问<!>“;集合的可扩展性如何?<!>

我们来谈谈对象的LINQ。一般来说,在大多数IEnumerable<T>实现迭代基础集合中的每个项目的程度上,LINQ具有很大的扩展能力。创建一个List<Foo>,其中包含一千万个项目,如下所示:

var list = from Foo f in fooList
           where f.Value = "Bar"
           select f;

会变慢。但这确实不是LINQ的错。你是那个给它一千万件物品清单的人。

如果LINQ不存在,你就像处理它一样处理它:通过构建Dictionaries和SortedLists等来帮助你减少搜索空间。

LINQ可以通过延迟查询执行来提高可伸缩性(以及更容易实现可伸缩性)。您可以使用一系列LINQ查询替换创建列表,将其过滤到新列表,过滤到新列表等的天真方法:

var list1 = from Foo f in fooList where f.Value1 = "Bar" select f;
var list2 = from Foo f in list1 where f.Value2 = "Baz" select f;
var list3 = from Foo f in list2 where f.Value3 = "Bat" select f;

所有这些都是通过底层集合执行的,当(以及是否)需要迭代最终列表时。但是,这并不是什么新鲜事:如果你没有LINQ,你可能最终会用一个做同样事情的方法替换你的天真方法。但是LINQ使它变得容易多了。

在我看来,LINQ 的目的是从开发的角度简化事情,而不是解决可伸缩性问题。

事实上,使用 LINQ 隐藏了许多复杂的内容,使事情变得如此简单,而且它 可以 铅,使用时 不负责任地, ,可扩展性问题。

其他答案中的例子比比皆是,但要提一下最重要的:

  • 如果您正在查询对象集合,则不能忽略它的大小。当有一些对象需要查询时,也许使用 LINQ 在模型中执行此操作听起来不错......但随着大小的增加,很明显查询应该在数据库中进行,而不是在模型中。

  • 例如,如果您使用 LINQ 自动生成 SQL,据我所知,您无法向数据库提供有关如何编译查询的提示 WITH (NOLOCK). 。随着表大小的增加,解决这些问题势在必行。

  • 与上面类似,但可能更通用:当您解决数据库的可扩展性问题时,您 必须 控制数据库正在做什么。拥有一种编译为 SQL 的语言,然后再次编译为执行计划,可以将控制权从您手中夺走。

  • 如果您必须更改数据库架构以使其更具可扩展性,并且您的代码由于没有存储过程而与其紧密相关,会发生什么情况?

  • 尽管看起来很简单,但您无法轻松更改 LINQ 提供程序:查询 SQL Server 与查询对象或查询 XML 不同。不过 LINQ 非常相似。我确实希望我的一些初级开发人员能够继续“LINQ 狂欢”,因为这比学习如何在考虑可扩展性的情况下做事更容易。

总之,我认为可以使用 LINQ 编写可扩展的代码,但前提是要小心使用它。没有杀手 工具, ,唯一的杀手 代码.

这在很大程度上取决于您使用的LINQ提供商以及您如何使用它。 LINQ可能并不知道具有惊人的执行速度,而是为开发人员提供了更高的生产力。

根据这个链接,即使有一些CTP,Linq to SQL在某些情况下已经比使用直接SQL更好。

如果您关注Speed并且正在使用LINQ来对象很多这里是一个codeplex项目(我认为)对于能够为您提供1000倍性能改进的提供商而言。

关于可扩展性的问题在某些方面取决于您使用LINQ的内容。在业务应用程序中,您不会发现很多SQL命令正在执行 - 它们很慢并且必须在DBMS中编译。你会看到的是很多存储过程调用。 LINQ中的这些会稍快一点。

请记住,LINQ to SQL等建立在ADO.NET的TOP之上 - 它们不是完全不同的方法或任何东西。当然,LINQ to XML将使用不同的API。这将非常类似于编译器 - 人类总能做出一些可能更快的优化,但在大多数情况下,这些API将能够生成比您自己编写的代码更快,更少错误的代码。

就扩展而言,如果要稍微分发数据或者可以使用SQL Server复制,则可以始终将LINQ置于Web服务之后。它的可扩展性不应低于ADO.NET。

可伸缩性和性能是两个不同但相关的东西。如果要测量性能,则需要查看一个框可以支持多少用户(例如)。当您测量可扩展性时,您可以添加另一个框,看看是否可以支持原始数量的两倍?不太可能,你可能只增加75%的处理能力,下一个只增加原始单位的50%,因此它会很快降到零。无论您以该速率添加多少个盒子,您都很幸运能够将支持的用户数增加一倍。这是可扩展性。

Linq模块如何扩展可能更多地取决于数据库,机器的强大程度,数据库的设计是什么,应用程序的设计是什么。

你经常会看到微观基准,它们应该揭示某些结论性的东西,但它们永远不会这样做,因为它们只是对整个问题的关键洞察。

你可以在这里拉出好的旧20/80例子。这个工具可能占20%,构成应用程序的各种有形物占80%。

如果您正在寻找一个真实的例子,stackoverflow大量使用Linq,请查看帖子/播客

使用Linq to SQL框架按需缓存和加载对象是有代价的。 如果一个对象可以根据需要延迟加载自身的一部分,那么很可能在每个对象中都有对数据上下文的引用。顺便提一下,数据上下文还会缓存从中请求的每个对象。这意味着如果您保留一个对象(在缓存中或仅仅因为稍后使用它),您不仅要保留该对象,而且还要保留数据上下文所请求的每个对象。这些将永远不会被垃圾收集,因为它们仍然被引用。

如果您的所有目标都具有较短的生命周期,并且应用程序每次执行新工作时都会创建新的DataContexts,则这不是问题。但我可以看到它是如何产生可扩展性问题的,如果有人不知道与每个对象一起出现的额外阻碍。

Linq在许多方面都是scalabile。

一个方面是linq背后的规范实现,它允许将Expression解释为以不同的语言(Linq2Sql,Linq2Hibernate)或在分布式计算环境(例如map-reduce集群)中耗尽进程( DryadLINQ

另一个方面是linq为语言提供的语义。如果您的提供程序支持延迟加载,您可以迭代数十亿个对象而无需在内存中填充集合,或者您可以对该查询进行并行化或优化(PLINQ或i4o)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top