Enrich-My-Library optimization

本文关键字:optimization Enrich-My-Library | 更新日期: 2023-09-27 18:03:00

声明:我是从c#来到Scala的,在那里我非常喜欢LINQ。因此,我很快就熟悉了迭代器和序列。我错过了"c#风格",但我能够用延续来烹饪我自己的…即使它付出性能损失。

现在,当我在c#中错过了集合中的一些方法时,我就把它定义为一个扩展方法,编译器在有效处理代码方面做得很好。在Scala中,我使用Pimp enrich My Library方法,但是我有点担心性能问题。

然而,与我的"yield迭代器"相反,这是一个公认的通用模式。Scala编译器是否对其进行了优化,删除了临时对象的创建?
class RichFoo(f: Foo) {
  def baz = f.bar()
  def baz2 = f.bar() * 2
}
object RichFoo {
  implicit def foo2Rich(f: Foo) = new RichFoo(f)
}
// on the caller side
val f : Foo = ....
f.baz
f.baz2
// this translates, literally, to new RichFoo(f).baz, new RichFoo(f).baz2

如果没有,为什么?对我来说,这是一个很好的安全优化。我可以"提示"或"强迫"编译器朝正确的方向运行吗?有哪些更快的替代方案?

我想在迭代器/可迭代器上使用我的算法集合模式,所以我可以将它们写成过滤器/映射/等collection.baz(lambda).bar(lambda2),但我担心它会被证明太"沉重"。(与更有效/直接,但丑陋的bar(lambda2, baz(lambda, collection)相比)

Enrich-My-Library optimization

正如@om-nom-nom注释的那样,这里(在2.10中)的解决方案是使用隐式值类。

implicit class RichFoo(val f : Foo) extends AnyVal {
  def baz = f.bar()
  def bax = f.bar()
}

RichFoo现在在编译时存在,但在运行时它被优化为静态方法调用,因此应该不会造成性能损失。

参见值类(SIP)

请参见Mark Harrah的《Introduction to Value Classes》,该书从用法的角度给出了一个很好的概述。