【问题标题】:Pattern matching with specialized in Scala使用 Scala 进行模式匹配
【发布时间】:2016-01-23 02:29:24
【问题描述】:

我有一个必须使用 Double 和 Float 的类。由于性能要求,我对(Double, Float) 使用带有@specialized 注释的泛型。我需要调用两个第三方函数。 ffunc(x: Float) 接受 Floatdfunc(y: Double) 接受 Double。在某些时候,我必须致电ffuncdfunc。为此,我使用 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

您能否建议将匹配代码替换为将被优化并避免装箱/拆箱的代码?

【问题讨论】:

    标签: scala pattern-matching bytecode boxing specialized-annotation


    【解决方案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 上。

    【讨论】:

    • 谢谢!它确实对我有用。它在字节码中产生虚拟调用,无需任何转换。
    • 看来可以做的更简单:scala> class X[@specialized(Int, Double) A] { def f(a: Int): String = "my int" }定义类X scala> val x = new X[Int]x:X[Int] = X$mcI$sp@2a3888c1 scala> x.f(42)res0:String = my int
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-02
    • 1970-01-01
    • 2012-12-08
    • 1970-01-01
    • 2018-06-14
    • 1970-01-01
    • 2016-05-17
    相关资源
    最近更新 更多