3

Double と Float で動作する必要があるクラスがあります。パフォーマンス要件のために、@specializedアノテーション付きのジェネリックを使用します。(Double, Float)呼び出す必要があるサードパーティ関数が 2 つあります。ffunc(x: Float)受け入れますFloatdfunc(y: Double)受け入れますDouble。ある時点で、またはのいずれかを呼び出すffunc必要がありdfuncます。そのために、scala パターン マッチングを使用します。私のコードは次のようになります。

class BoxingTest[@specialized(Double, Float) T] {
  def foo(p: T): Unit = {
    p match {
      case dp: Double => dfunc(dp)
      case df: Float => ffunc(df)
    }
  }
}

ただし、scala コンパイラは、特殊化されたバージョンに対して最適化されていないバイトコードを提供します。特殊化されたクラスのバイトコードの内部を見ると、特殊化された型をオブジェクトに変換する最適化されていない一致するコードが表示されます。次のように、追加のボックス化/ボックス化解除もあります。

41: invokestatic  #21                 // Method scala/runtime/BoxesRunTime.boxToDouble:(D)Ljava/lang/Double;
44: invokestatic  #39                 // Method scala/runtime/BoxesRunTime.unboxToDouble:(Ljava/lang/Object;)D

一致するコードを、最適化され、ボックス化/ボックス化解除を回避するコードに置き換えることを提案できますか?

4

1 に答える 1

1

これは以前に出てきました。最善の策は、特殊なメソッドをオーバーライドすることだったと思います:

scala> class X[@specialized(Int, Double) A] { def f(a: A): String = ??? }
defined class X

scala> trait T { def f$mcI$sp(i: Int): String = "my int" }
defined trait T

scala> val x = new X[Int] with T
x: X[Int] with T = $anon$1@6137cf6e

scala> x.f(42)
res0: String = my int

それはおそらくSOでした。

于 2016-01-23T09:39:34.343 に答える