对JVM的哪些更改最有利于Scala编译器和运行时?
通过引入计划到达JVM 7的 InvokeDynamic 字节代码,动态语言将在性能上受益匪浅,Scala可能会受益于尾递归(不确定它是否会出现在JVM 8或更高版本中) .
InvokeDynamic
Scala及其现有功能集可以从JVM中获益吗?这些变化即将到来吗?
具体来说,JVM是否会对闭包和函数作为对象提高性能?
基本上,约翰罗斯一直在竞选的一切:)
Fixnums - 消除装箱/拆箱原语的费用 .
方法句柄 - 将加速高阶函数并允许JVM更有效地优化它们 . SAM类型有时可能需要在单态和多态呼叫站点之间进行笨拙的翻转/翻转,以防止内联 .
Continuations - 根据node.js支持异步/并发设计
Interface Injection - 简化mixin组合和角色的实现,以及在许多情况下无需生成某些中间类并使结构类型成为可能而无需反映的需要 .
尾巴调用优化 - 应该是一个不用脑子:)
通常会引用Reification作为有利于Scala模式匹配的内容,但考虑到两种语言使用的不同方差方案,这在interop方面会产生很高的成本 . 在这一点上,我认为物化实际上可能造成的伤害远远超过它的好处 .
我还认为期望任何会破坏Java的向后兼容性是不合理的 . 这不会发生 .
Scala有一些功能可以在JVM中更好地实现,例如:
可在运行时访问的泛型 . 目前,scalac将泛型类型保存为隐藏字段(如果有问题的类是案例类) . 这使得泛型在案例类中不必要地昂贵 .
声明 - 站点差异 . Scala在定义站点指定类型参数的方差,而Java在调用站点处这样做 . 虽然这不太可能得到修复,因为它会破坏所有现有的Java通用代码 .
尾调用优化 . Scalac可以自己做一些尾调用优化,但只能在最简单的(自递归)情况下进行 . 任何其他尾调用都将使用堆栈空间,就像在JVM中一样 .
删除空指针 . Scala已经可以使用 Option[A] 来处理空引用,但由于存在于JVM上,对选项本身的引用可能为null,或者它像Haskell一样得到非空的保证 .
编辑:向列表添加声明站点方差 .
对于元组和case类,值类型将有助于提高性能 . 转义分析有助于减少这些对象的堆分配,但目前JVM无法积极地内联某些方法调用,因此无法消除这些小的不可变对象的堆分配 . 这导致堆垃圾并且执行时间增加3-4倍 .
值类型还有助于增加数据位置并减少内存使用量 . 例如,在一个简单的Array [(Int,Int)]中,每个数组条目都有一个指针对象头的开销 . 使用值类型,可以完全消除此开销 .
人们经常关注InvokeDynamic - 没有意识到MethodHandles框架有很多其他优点,即使MH提供的方法引用永远不会被动态调用 .
MethodHandles几乎就像是“反射就做对了”的高性能形式 .
任何大量使用反射的语言都可以从语言运行时中使用MethodHandles中获益 .
4 回答
基本上,约翰罗斯一直在竞选的一切:)
Fixnums - 消除装箱/拆箱原语的费用 .
方法句柄 - 将加速高阶函数并允许JVM更有效地优化它们 . SAM类型有时可能需要在单态和多态呼叫站点之间进行笨拙的翻转/翻转,以防止内联 .
Continuations - 根据node.js支持异步/并发设计
Interface Injection - 简化mixin组合和角色的实现,以及在许多情况下无需生成某些中间类并使结构类型成为可能而无需反映的需要 .
尾巴调用优化 - 应该是一个不用脑子:)
通常会引用Reification作为有利于Scala模式匹配的内容,但考虑到两种语言使用的不同方差方案,这在interop方面会产生很高的成本 . 在这一点上,我认为物化实际上可能造成的伤害远远超过它的好处 .
我还认为期望任何会破坏Java的向后兼容性是不合理的 . 这不会发生 .
Scala有一些功能可以在JVM中更好地实现,例如:
可在运行时访问的泛型 . 目前,scalac将泛型类型保存为隐藏字段(如果有问题的类是案例类) . 这使得泛型在案例类中不必要地昂贵 .
声明 - 站点差异 . Scala在定义站点指定类型参数的方差,而Java在调用站点处这样做 . 虽然这不太可能得到修复,因为它会破坏所有现有的Java通用代码 .
尾调用优化 . Scalac可以自己做一些尾调用优化,但只能在最简单的(自递归)情况下进行 . 任何其他尾调用都将使用堆栈空间,就像在JVM中一样 .
删除空指针 . Scala已经可以使用 Option[A] 来处理空引用,但由于存在于JVM上,对选项本身的引用可能为null,或者它像Haskell一样得到非空的保证 .
编辑:向列表添加声明站点方差 .
对于元组和case类,值类型将有助于提高性能 . 转义分析有助于减少这些对象的堆分配,但目前JVM无法积极地内联某些方法调用,因此无法消除这些小的不可变对象的堆分配 . 这导致堆垃圾并且执行时间增加3-4倍 .
值类型还有助于增加数据位置并减少内存使用量 . 例如,在一个简单的Array [(Int,Int)]中,每个数组条目都有一个指针对象头的开销 . 使用值类型,可以完全消除此开销 .
人们经常关注InvokeDynamic - 没有意识到MethodHandles框架有很多其他优点,即使MH提供的方法引用永远不会被动态调用 .
MethodHandles几乎就像是“反射就做对了”的高性能形式 .
任何大量使用反射的语言都可以从语言运行时中使用MethodHandles中获益 .