如何将Scala @specialized用于围绕基元的内存高效包装类?
发布时间:2020-12-16 09:57:36 所属栏目:安全 来源:网络整理
导读:我有一个包装类,可以存储Long,Double或Boolean原始值(以及为简单起见我已删除的其他一些东西).我原来的天真实现只是将包装的值存储在Any类型的字段中,这导致值被装箱. 为了删除装箱并减少内存使用量,我尝试使用泛型,但了解到由于类型擦除,这不会保存任何东西
我有一个包装类,可以存储Long,Double或Boolean原始值(以及为简单起见我已删除的其他一些东西).我原来的天真实现只是将包装的值存储在Any类型的字段中,这导致值被装箱.
为了删除装箱并减少内存使用量,我尝试使用泛型,但了解到由于类型擦除,这不会保存任何东西.所以我尝试使用@specialized,但得到了惊人的结果. 下面的代码是使用scalac 2.9.3构建的,并在JDK7上运行. MemoryMeasurer来自here,我相信它是准确的. “填充”字段不重要;我只是用它来填充基础对象(没有包装的值)到16个字节,所以我的各种尝试的效果更清楚. import objectexplorer.MemoryMeasurer class GenericNonSpecialized[A] (wrapped: A,val padding: Int) { def getWrapped: Any = wrapped } class GenericSpecialized[@specialized(Long,Double,Boolean) A] (wrapped: A,val padding: Int) { def getWrapped: A = wrapped } class GenericSpecializedVal[@specialized(Long,Boolean) A] (val wrapped: A,val padding: Int) { def getWrapped: A = wrapped } class NonGeneric(val wrapped: Long,padding: Int) { } object App { def main(args: Array[String]) { println(MemoryMeasurer.measureBytes(new GenericNonSpecialized(4L,0))) // Expect: 48: NonSpecialized object (24 bytes) + boxed long (24 bytes) // Actual: 48 // I expect all of the below to be 24 bytes: Object overhead (12 bytes) + Long (8 bytes) + Int (4 bytes),// but only the non-generic one is actually 24 bytes. println(MemoryMeasurer.measureBytes(new GenericSpecialized(4L,0))) // 56 println(MemoryMeasurer.measureBytes(new GenericSpecializedVal(4L,0))) // 32 println(MemoryMeasurer.measureBytes(new NonGeneric(4L,0))) // 24 } } 问题: >如何创建使用24个字节的通用包装器对象,如非通用等效项? (我最好的尝试,GenericSpecializedVal使用32) 解决方法
不幸的是,专门的类继承自非专用父类,并且包含用于装箱副本的存储空间.因此,简短的答案是你不能以这种方式形成一个有效的包装器.
您可以在特征中声明数据: trait Boxer[@specialized A]{ def boxed: A } 然后手动提供实现: class BoxerInt(val boxed: Int) extends Boxer[Int] class BoxerDouble(val boxed: Double) extends Boxer[Double] 然后编写Boxer伴侣来重载apply方法: object Boxer { def apply(i: Int) = new BoxerInt(i) def apply(d: Double) = new BoxerDouble(d) } 所以你可以让它看起来像你不必做所有的工作: val box = Boxer(5.0) 但它与其他专业化用途仍然不完全无缝(特别是在通用上下文中的创建始终是一个问题). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |