代码之家  ›  专栏  ›  技术社区  ›  ziggystar

Scala中通过隐式“装箱”原语类型的开销

  •  5
  • ziggystar  · 技术社区  · 14 年前

    假设我想要一个类似Java的类 Date . 它唯一的数据成员是long,它表示自1970年以来的毫秒数。

    制作一个新的Scala类型是否有任何性能优势:

    type PrimitiveDate = Long
    

    然后可以使用隐式转换添加方法,就像对int使用 RichInt . 将原始类型“装箱”到富类中是否涉及任何开销(类创建)?基本上你可以用一个静态方法

    def addMonth(date: PrimitiveDate, months: Int): PrimitiveDate = date + 2592000000 * months
    

    让类型系统知道它必须在 d addMonth 5 出现在代码中。

    编辑

    似乎您通过编写 type PrimitiveDate = Long 不是由scala编译器强制的。在Scala中创建一个适当的类(包含Long)是创建强制类型的唯一方法吗?

    您认为能够为基元类型创建强制类型别名有多大用处?

    3 回复  |  直到 14 年前
        1
  •  11
  •   Community arnoo    7 年前

    好, escape analysis 丰富的包装 为了呼叫 addMonth 方法。

    在多大程度上 实际发生 显然将取决于运行时 热点 JVM决定在对象创建中添加这些方法。当escape分析不发生时,显然JVM必须“框”(如您所说) Long 在包装类的新实例中。它不涉及“类创建”-它将涉及“创建类的实例”。这个实例,如果是短生命的,那么将立即被GC-d,因此开销(虽然很小)是:

    • 实例的内存分配

    很明显,只有当您确实在编写非常低的延迟代码时,如果您试图最小化垃圾创建(在一个紧密的循环中),这些问题才会成为任何类型的问题。只有你知道是不是这样。

    至于这种方法是否对你有用(逃逸分析有助于你),你必须在野外进行测试。众所周知,为这类事情编写微基准非常困难。


    我不太喜欢这些类型别名的原因 作为公共API的一部分 scala并没有像我希望的那样严格地执行它们。例如:

    type PrimitiveDate = Long
    type PrimitiveSpeed = Long
    type Car = String
    type Meeting = String
    
    var maxSpeeds : Map[Car, PrimitiveSpeed] = Map.empty
    
    //OOPS - much too easy to accidentally send the wrong type
    def setDate(meeting : Meeting, date : PrimitiveDate) = maxSpeeds += (meeting -> date)
    
        2
  •  4
  •   Kevin Wright    14 年前

    在给定的示例中,实际上还没有创建新类型,它只是预先存在的长类型的别名。

    type Grid = Seq[Seq[Int]] 避免指定 Seq[Seq[Int]]

    你可以很高兴地通过 Long 一种方法 PrimitiveDate 方法,尽管你 其优点是代码可以更好地自我记录。

    如果您真的想创建一个具有强制类型安全性和方便的模式匹配的新类型,我将使用case类:

    case class PrimitiveDate(value:Long)
    

    而且,为了方便起见,甚至可能提供隐式Long=>PrimitiveDate转换。

        3
  •  3
  •   itsbruce    9 年前

    在你问了这个问题11个月后,迈尔斯·萨宾发现了一种非常简单、优雅和高效的创作方法 unboxed newtypes 在斯卡拉。与类型别名不同,类型标记是强制的。原语类型需要最少的样板(每个原语一行)来提供专门化。

    一年后,他又加了一个 more polished and robust version 从这个到 Shapeless . 如果你不想要这个优秀的库的其余部分,这个概念是简单和简洁的,可以在一个项目中复制而不添加shapelize。

    当然,你和回答你问题的人可能都知道这一点,但值得在这里补充一点,因为这仍然是一个重要的问题。