【问题标题】:Implementing a fixed size, immutable, and specialized vector实现固定大小、不可变和专用的向量
【发布时间】:2012-04-21 09:28:25
【问题描述】:

为了性能和安全,我想实现一个固定大小的向量,它既不可变又专门化(我需要快速算术)。我的第一个想法是使用@specialized 注释(因为我需要整数和实数)。

这是第一次尝试:

package so
class Vec[@specialized A] private[so] ( ary: Array[A] ) {
  def apply( i: Int ) = ary(i)
}

但是,当我使用javap 分析生成的字节码时,我可以看到元素仍然被装箱。例如:

public double apply$mcD$sp(int);
  Code:
   0:   aload_0
   1:   iload_1
   2:   invokevirtual   #33; //Method apply:(I)Ljava/lang/Object;
   5:   invokestatic    #83; //Method scala/runtime/BoxesRunTime.unboxToDouble:(Ljava/lang/Object;)D
   8:   dreturn

看起来数组不是专门化的,这看起来很傻,因为数组是专门在 JVM 上的。

我还能做些什么来达到我的目标吗?

【问题讨论】:

  • 你用的是什么版本? 2.9.2 对我来说看起来不错。
  • 我尝试了 2.9.2 和 2.8.2。

标签: scala autoboxing specialized-annotation


【解决方案1】:

您可能正在查看编译为 Vec.class 的代码。根据this thread,专业化发生在子类中。这可以在 REPL 中验证:

scala> class Vec[@specialized A] ( ary: Array[A] ) {
     |   def apply( i: Int ) = ary(i)
     | }
defined class Vec

scala> new Vec( Array[Int](1) ).getClass
res0: java.lang.Class[_ <: Vec[Int]] = class Vec$mcI$sp

如您所见,Int 使用的是子类 Vec$mcI$sp。如果您在该类上运行 javap,您会发现它实际上正确地专门化了代码。这是使用 javap 在Vec$mcI$sp.class 中应用方法的样子:

  public int apply(int);
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0       
         1: iload_1       
         2: invokevirtual #13                 // Method apply$mcI$sp:(I)I
         5: ireturn       

我想这是您在使用 Int 时想要的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-29
    • 2013-02-13
    • 1970-01-01
    • 2018-04-21
    • 2013-06-16
    • 1970-01-01
    • 2016-01-25
    相关资源
    最近更新 更多