Java 8 的 stream API 和 C# 的 LINQ 哪个更慢?

一方面,Java 8 提供的 lambda 在 JVM 层本身就需要 invokedynamic 这样的黑魔法,产生了性能损失。 另一方面,.Net …
关注者
233
被浏览
56,527

6 个回答

Java 不了解,我只谈一下Linq。

题主说的应该只是 Linq To Objects,也就是 Enumerable 实现的一堆扩展方法。Reverse 为什么那么实现是因为 IEnumerable 的限制,它并没有 IReadOnlyCollection 的 Count,也没有 IReadOnlyList 的随机访问,再加上 c# 并没有模板特化之类的特性,所以在语言和库能做的优化实在有限。另外 RyuJIT 的优化也不能让人满意,devirtualize 不知道什么时候实装。

如果就整个 Linq 来看,优势应该是扩展性,比如 Linq To Entities、Linq To SQL、Linq To WMI等等,库作者只需要实现 QueryProvider 就能把 LinqExpression 翻译成另一种语言或者操作。而对用户来说学习成本很低,不管是查询什么都是同一套语法和类似的函数。

正因为很好的扩展性,Linq To Objects 的性能问题也就有了解决办法: LinqOptimizer 就是这样一个库,把 Linq 查询进行了编译(不过它不是通过实现 QueryProvider 的方式),生成了基于 for 循环的代码,性能是原来的15倍。

.Net 的 LINQ 的实现烂,JIT没法内联优化 LINQ 查询,CLR 速度不如 JVM 也都是事实。



你说的这仨事实为啥我一个都不知道?




至于invokedynamic又怎么黑魔法了,又怎么就一定会产生性能损失了,还有,这和stream API又有啥关系?

没记错的话,stream API用的也是SAM,而不是invokedynamic