[swift-evolution] [Proposal] Sealed classes by default
mark.lacey at apple.com
Tue Jun 28 18:41:49 CDT 2016
> On Jun 28, 2016, at 4:01 PM, Michael Peternell via swift-evolution <swift-evolution at swift.org> wrote:
>> Am 29.06.2016 um 00:32 schrieb John McCall <rjmccall at apple.com>:
>> The decision to make class methods polymorphic by default was always premised on being able to undo that in obvious cases where methods are never overridden. Making a class public so that clients can use it shouldn't cause significant performance degradations just because you forgot to also write "final".
> I do care about performance. For this reason I don't want a fully dynamic language. I disagree about the "significant performance degradations just because you forgot to also write `final`". I mentioned "performance" in my original post only because it would be the only convincing argument - if there were indeed superior performance when using `final`.
There is, and it can be very substantial. Knowing a method is final enables the optimizer to devirtualize, and devirtualization enables type-based specialization for generic functions, as well as inlining (each of which enable further devirtualization, etc., etc.). Devirtualization also makes it possible to do specialization of function signatures, which can remove ARC overhead. When that kicks in it can be a substantial win by itself. It can also improve the results of interprocedural analysis, which can provide further benefit (and which we’ll likely rely on more for performance improvement in the future). For example we are currently able to stack-allocate some data that was heap allocated in Swift 2.x because we do escape analysis, which is only possible when you know all the potential callees at a call site.
I recall seeing performance differences of 40x (yes, 40x, not 40%) on small-to-moderately sized benchmarks that use generics due to whole module optimization being able to infer final for internal classes. Part of that performance difference can be accounted for by known issues with the performance of generic code, but even if we substantially improve that I believe we would still have cases where lack of devirtualizing, inlining, and specialization would result in substantially slower code.
> Of course, dynamic dispatch is much slower than static dispatch. But optimized code does not spend much time dispatching. If a method takes 3 seconds to complete, and from that 2 seconds are used for dynamically dispatching method calls, then I would say that it has not been optimized for performance yet. How would such a function look like? The function being dynamically dispatched should probably not be statically dispatched but inlined completely. And for the rare case that the dispatch type really makes all the difference, it's always possible to `final`ize (or `private`ize) some of the used methods.
> swift-evolution mailing list
> swift-evolution at swift.org
More information about the swift-evolution