简体   繁体   中英

Pattern matching with specialized in Scala

I have a class that must work with Double and Float. I use generic with @specialized annotation for (Double, Float) due to performance requirements. There are two third-party functions, that I need to call. ffunc(x: Float) accepts Float , dfunc(y: Double) accepts Double . At some point I have to call either ffunc or dfunc . I use scala pattern matching for that purpose. My code looks as follows:

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

However, scala compiler provides non-optimized bytecode for specialized versions. When I look inside the bytecode of specialized class, I see the non optimized matching code that converts my specialized type to object. There are also additional boxing/unboxing as follows:

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

Could you suggest a replacement of matching code with the code that will be optimized and will avoid boxing/unboxing?

This came up previously. I think the best bet was to override the specialized method:

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

That was probably on SO.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM