0__*_*0__ 13 performance visibility scala
private[this] def与仅仅相比,写作在性能与噪声比方面是否有意义private def?我的理解是,使有关差别private[this] val过private val,因为前者允许scalac创建一个实际的领域.但也许因为def它没有区别?最后,怎么样private[this] var?
有一个非常相似的问题,但它没有包含有关性能的具体陈述.
不,没有任何性能优势.双方private def并private[this] def会转换为private或public取决于它们是否来自一个不同的类调用,而不是根据什么他们在斯卡拉能见度在字节码的方法.
让我们从Scala语言规范所说的内容开始private[this]:
它只能从定义它的对象中访问.也就是说,选择pM仅在前缀为this或O.this时才合法,对于包含引用的某个类O. 此外,对不合格私人的限制适用.
您可以看到规范只是说出语法上可接受的内容.二者private并private[this]可以从同一类或内类的实例仅调用.在字节码中,您只能区分类级别的访问,而不是实例级别.因此,两个选项在字节码中应该相同,Scala仅在编译期间强制执行差异.
首先,让我们看一个简单的例子:
class MyClass {
private def privateDef(x: Int) = x
private[this] def privateThisDef(x: Int) = x
}
Run Code Online (Sandbox Code Playgroud)
这被转换为字节码为
public class MyClass {
private int privateDef(int);
private int privateThisDef(int);
public MyClass();
}
Run Code Online (Sandbox Code Playgroud)
如您所见,两种方法最终都是private,因此与JVM的观点没有区别(例如关于内联,静态/动态绑定等).
当我们添加内部类时,这会如何变化?
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)
}
}
Run Code Online (Sandbox Code Playgroud)
这被翻译成了
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);
}
Run Code Online (Sandbox Code Playgroud)
你可以看到,这次,两个方法MyClass都是公共的,以便内部类可以调用它们.再次,private和之间没有区别private[this].
当一个私有方法可以从另一个类调用时 - 当你从它的各个类中的一个伴随对象调用一个私有方法时,Scala又增加了一个特殊情况.一个伴随对象MyClass将是一个以MyClass$字节码命名的单独类.private在伴随中调用方法会跨越类边界,因此这种方法将在字节码中公开.
你不能private[this]在同伴之外调用方法,但这只是一种语法限制.无论您在哪里private和之间进行选择private[this],结果在字节码中都是相同的.
变量的行为似乎与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
}
}
Run Code Online (Sandbox Code Playgroud)
被编译为
public class MyClass {
private int privateVar;
private int privateThisVar;
private int MyClass$$privateVarForInner;
public int MyClass$$privateThisForInner;
// ...
}
Run Code Online (Sandbox Code Playgroud)
然后内部类使用setter for privateVar和field access privateThisVar.我不确定scalac为什么会这样,我在规范中找不到任何东西.也许这是特定于实现的东西.
编辑:根据要求,我创建了一个小的JMH 基准,比较获取和设置a private var和的性能private[this] var.结果?? 10??根据JMH,所有操作都是根据.差异可以忽略不计,内部类和vars的情况无论如何都是罕见的.
| 归档时间: |
|
| 查看次数: |
717 次 |
| 最近记录: |