3

我有一個類必須使用Double和Float。由於性能要求,我使用通用@specialized註釋(Double, Float)。有兩個第三方功能,我需要打電話。 ffunc(x: Float)接受Floatdfunc(y: Double)接受Double。在某些時候,我必須打電話ffuncdfunc。我爲此使用了scala模式匹配。我的代碼如下所示:與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 

你可以建議更換與將進行優化,將避免裝箱/拆箱的代碼相匹配的代碼?

回答

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 = [email protected] 

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

這可能是在SO上。

+0

http://stackoverflow.com/a/34279354/1296806 –

+0

謝謝!它爲我工作。它在字節碼中產生虛擬調用而沒有任何轉換。 – Alexander

+0

似乎是可以做到的更簡單: '階>類X [@specialized(中間體,雙)A] {DEF F(一的:int):字符串= 「我的整數」}' 定義的類X 'scala> val x = new X [Int]' x:X [Int] = X $ mcI $ sp @ 2a3888c1 'scala> xf(42)' res0:String = my int – Alexander