12

パフォーマンスと安全性のために、不変で特殊化された固定サイズのベクトルを実装したいと思います (高速演算が必要です)。私の最初のアイデアは、@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で特殊化されているため、配列は特殊化されていないように見えますが、これはばかげているようです。

目標を達成するためにまだできることはありますか?

4

1 に答える 1

9

Vec.class にコンパイルされたコードを見ている可能性があります。このスレッドによると、特殊化はサブクラスで発生します。これは 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 を実行すると、実際にはコードが適切に特殊化されていることがわかります。これは、Vec$mcI$sp.classjavap を使用した場合の apply メソッドの外観です。

  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

于 2012-04-21T17:44:12.823 に答える