performance - `private[this] def` 何时比 `private def` 具有性能优势?

标签 performance scala visibility

private[this] defprivate def 相比,在性能噪声比方面是有意义的?我知道这对 private[this] val 有影响超过 private val因为前者允许 scalac 创建一个实际的字段。但也许对于 def没有什么不同的?最后,private[this] var 怎么样? ?

有一个very similar question ,但它不包含有关性能的具体陈述。

最佳答案

简短的回答

不,没有任何性能优势。两个private defprivate[this] def被翻译成 privatepublic字节码中的方法取决于它们是否从不同的类中调用,而不取决于它们在 Scala 中的可见性。

理论

让我们从 Scala language specification 的内容开始。说private[this] :

it can be accessed only from within the object in which it is defined. That is, a selection p.M is only legal if the prefix is this or O.this, for some class O enclosing the reference. In addition, the restrictions for unqualified private apply.



您可以看到规范只是说明了语法上可接受与否的内容。两个privateprivate[this]只能从同一类或内部类的实例中调用。在字节码中,您只能区分类级别的访问,而不是实例级别。因此,两个选项在字节码中应该是相同的,而 Scala 仅在编译期间强制执行差异。

基本案例

首先,让我们看一个简单的例子:
class MyClass {
    private def privateDef(x: Int) = x
    private[this] def privateThisDef(x: Int) = x
}

这被翻译成字节码为
public class MyClass {
   private int privateDef(int);
   private int privateThisDef(int);
   public MyClass();
}

如您所见,这两种方法都以 private 结尾。 ,因此从 JVM 的角度来看没有区别(例如,关于内联、静态/动态绑定(bind)等)。

内部类

当我们添加内部类时,这将如何改变?
class MyClass {
  private def privateDef(x: Int) = x
  private[this] def privateThisDef(x: Int) = x

  class MyInnerClass{
    MyClass.this.privateDef(1)
    MyClass.this.privateThisDef(2)
  }
}

这被翻译成
public class MyClass {
  public int MyClass$$privateDef(int);
  public int MyClass$$privateThisDef(int);
  public MyClass();
}
public class MyClass$MyInnerClass {
  public final MyClass $outer;
  public MyClass MyClass$MyInnerClass$$$outer();
  public MyClass$MyInnerClass(MyClass);
}

可以看到,这一次,MyClass 中的两个方法是公共(public)的,以便内部类可以调用它们。同样,private 之间没有区别和 private[this] .

同伴

当可以从不同的类调用私有(private)方法时,Scala 添加了另一种特殊情况 - 当您从其各自类中的伴随对象调用私有(private)方法时。 MyClass 的伴随对象将是一个名为 MyClass$ 的单独类在字节码中。调用private同伴中的方法跨越类边界,因此这种方法将在字节码中公开。

您不能调用private[this]同伴之外的方法,但这只是一个语法限制。任你选择privateprivate[this] ,结果在字节码中是一样的。

变量

vars 的行为似乎与 defs 的行为有些不同。这节课
class MyClass {
  private var privateVar = 0
  private[this] var privateThisVar = 0
  private var privateVarForInner = 0
  private[this] var privateThisForInner = 0

  class MyInnerClass{
    privateVarForInner = 1
    privateThisForInner = 1
  }
}

编译为
public class MyClass {
  private int privateVar;
  private int privateThisVar;
  private int MyClass$$privateVarForInner;
  public int MyClass$$privateThisForInner;
  // ...
}

然后内部类对 privateVar 使用 setter和 privateThisVar 的字段访问权限.我不确定为什么 scalac 会这样,我在规范中没有找到任何东西。也许这是特定于实现的东西。

编辑:根据要求,我创建了一个小型 JMH benchmark比较获取和设置 private var 的性能和 private[this] var .结果?所有操作都是≈ 10⁻⁸ s 根据 JMH。差异可以忽略不计,内部类和 var 的情况s 是很少见的。

关于performance - `private[this] def` 何时比 `private def` 具有性能优势?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36849761/

相关文章:

c# - IQueryable、ICollection、IList 和 IDictionary 接口(interface)之间的区别

eclipse - 你如何在 Eclipse 中对 Scala 进行单元测试?

javascript - 高效获取元素可见区域坐标

python - dict.__setitem__(key, x) 是否比 dict[key] = x 慢(或快),为什么?

reactjs - 为什么我的 Next JS 性能得分在 web.dev 中如此不一致?

c++ - 文件c++的写入性能

scala - Spark - 查找两个不同列中每个不同值的总出现次数

google-app-engine - scala 的谷歌应用引擎上的异步?

c# - 为什么 Columns 在调用 DataGridView.Columns.Clear() 后不保持隐藏状态?

java - 如何从头到尾逐渐显示一个字符串(可见性)?