简体   繁体   English

叶节点类中的Sealed关键字

[英]Sealed keyword in leaf node classes

While I understand that sealed can be used for security reasons, a few people use the sealed keyword on leaf nodes as an optimization technique. 虽然我知道出于安全原因可以使用密封的,但仍有少数人在叶节点上使用密封的关键字作为优化技术。

How does this help optimization? 这如何帮助优化? Why isn't the compiler smart enough to figure this out itself? 为什么编译器不够聪明,无法自行解决?

Suppose you have a virtual method which is overridden in a leaf class. 假设您有一个在叶子类中覆盖的虚拟方法。 This certainly won't be overridden any further, so the JIT compiler could potentially inline calls to that method for targets which are known to be of that leaf class. 当然,这不会被进一步覆盖,因此JIT编译器可以潜在地内联调用该方法,以用于已知属于该叶类的目标。 I don't know whether the JIT actually performs this optimization, mind you. 请注意,我不知道JIT是否实际上执行了此优化。

Note that in Java, the HotSpot JVM can perform this optimization even for non-final classes, as it's a multi-pass JIT: it can optimistically assume that nothing's going to override a virtual method, and then undo its optimisations if a class is ever loaded that does override it. 请注意,在Java中,HotSpot JVM甚至可以对非最终类执行此优化,因为它是一次多次传递的JIT:它可以乐观地假设没有任何东西可以覆盖虚拟方法,如果某个类曾经存在过,则可以撤消其优化。加载, 会覆盖它。 Of course, with methods being virtual by default in Java, this is a bigger deal than it would be in C#. 当然,在Java中默认使用虚拟方法的情况下,这比在C#中要大得多。 (Even if defaults shouldn't matter, they clearly do.) (即使违约不应该的问题,他们显然做的。)

Personally I don't use sealed particularly for optimization or security reasons: I use it because designing for inheritance (properly) is hard . 就个人而言,我并不是特别出于优化或安全原因而使用sealed :之所以使用它,是因为(适当地)设计继承非常困难 I agree with the concept of "design for inheritance or prohibit it" and have generally found that the occasional pain of not being able to derive from a class is more than compensated for by the freedom from worrying about inheritance. 我同意“为继承而设计或禁止继承”的概念,并且通常发现,无法从一个类派生出来的偶然痛苦,可以通过担心继承的自由得到补偿。 YMMV. YMMV。

No, it does not really help in terms of optimization. 不,在优化方面并没有真正的帮助。 Not what I can see from profiling anyways. 反正我从剖析中看不到什么。

In a sealed class, calls to virtual methods can bypass the usual virtual method lookup and go directly to the most-derived virtual method implementation instead. 在密封的类中,对虚拟方法的调用可以绕过常规的虚拟方法查找,而直接转到最派生的虚拟方法实现。 In principle, the compiler/JIT could also inline these calls. 原则上,编译器/ JIT也可以内联这些调用。

The compiler can't figure it out for non-sealed classes, because any code could come along after compilation and inherit from your class: the compiler must assume the worst case. 对于非密封类,编译器无法解决,因为任何代码都可以在编译后出现并从您的类继承:编译器必须假定最坏的情况。

It is a bit of a false optimisation; 这有点不正确。 I'd rather use it to make sure that if I'm not expecting inheritance I don't get inheritance. 我宁愿用它来确保,如果我不期待继承我没有得到继承。 The compiler still emits all instance calls (to classes) as virtual calls, but potentially the JIT could optimize it differently, and just do a null check and static call, if not overridden. 编译器仍将所有实例调用(对类)作为虚拟调用发出,但是潜在的JIT可以对其进行不同的优化,并且如果不进行覆盖,则只需执行null检查和静态调用即可。 Possibly. 可能吧。

There are some more esoteric cases, for example when the presence of a particular interface would cause it to be treated differently at runtime - but to exploit those scenarios (depending on sealed ) requires runtime code generation via ILGenerator etc. 还有一些更深奥的情况,例如,当特定接口的存在会导致在运行时对它进行不同的处理时-但是要利用这些情况(取决于sealed ),需要通过ILGenerator等生成运行时代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM