scala中的@specialized

Posted 刀哥的学习园地

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了scala中的@specialized相关的知识,希望对你有一定的参考价值。

scala中的@specialized

为什么需要@specialized

@specialized 是为了解决由于泛型擦除而需要对基础数据类型进行装箱/拆箱操作所带来的性能问题

@specialized  scala2.8 开始加入的,为什么要增加呢?

Java/Jvm的泛型是类型擦除的,也就是说泛型编译时会被丢弃,全部向上转型为 Object, 因此对基础数据类型(primitive) 来说, 无法直接使用基础数据类型
作为泛型参数,如 List<int> 是不可以的,所以就有了 Box  Unbox, 将 int 装箱为 Integer , double 装箱为 Double, 等等。

带来的问题是内存的增加, double 本身只需要 8 个字节,装箱为 Double 后,将需要 24 个字节,对于一些有庞大集合的应用来说,很可能会带来内存的
性能瓶颈。

Scala由于需要编译为Java字节码,因此也就继承了Java/JVM这个缺陷,为了改进这个缺陷,Scala增加了 @specialized 注解,来指示Scala编译器来规避这个问题

@specialized 是如何解决的

首先,Scala语言标准库中定义了 specialized 来告知编译器针对泛型进行优化:

class specialized(group: SpecializedGroup) extends 
 scala.annotation.StaticAnnotation {  
 def
this(types: Specializable*) = this(new Group(types.toList))   def this() = this(Primitives) }

其次,针对设置了 @specialized 的泛型类型,Scala编译器会针对特定的基础数据类型生成特定版本的代码,例如:

import scala.{specialized => sp}
trait Eq[@sp(Int) T] extends Any with Serializable {self =>   
 def
eqv(x: T, y: T):
Boolean }

 scalac -print 进行编译便可看见结果,如果 @sp 不指定类型,则会生成所有基础数据类型的特定版本。

需要注意的问题

固然 @specialized 通过特化版本的方式能够提高性能,但也是有缺点的:
1. 会产生大量的特化版本的类,导致运行时需要加载更多的类型
2. 如果有泛型依赖,被依赖中的泛型没有设置 specialized 就算设置了,也不会被特化,因此有一定的局限性

参考资料

  1. Specializing for primitive types  http://www.scala-notes.org/2011/04/specializing-for-primitive-types/

  2. Specialization - Dragos http://days2010.scala-lang.org/node/138/151/






以上是关于scala中的@specialized的主要内容,如果未能解决你的问题,请参考以下文章

错误:我的代码中出现意外的符号/输入/字符串常量/数字常量/SPECIAL

Rust 1.7.0 语法基础 sep_token 和 non_special_token

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

VSCode自定义代码片段——JS中的面向对象编程

VSCode自定义代码片段9——JS中的面向对象编程

避免从Special:Random中使用缓存进行重定向