5 ms·
anything similar for higher level languages (c# or the likes)?
by rottyguy 13y ago
anything similar for higher level languages (c# or the likes)?
- CmonDev 13y agoI think there is usually something else to optimize before this becomes a problem. And if it becomes a problem you need a low-level language anyway?
- MichaelGG 13y agoBut in cases of needless virtual calls (doesn't Java default to virtual for some strange reason?) it may be a quick and easy win. Additionally, it's not always so easy to drop to a low-level language. If your architecture is enormous and complicated, it might be totally unfeasible to change languages for hot parts.
- army 13y agoIn Java, all methods are virtual. You can often achieve a similar effect to non-virtual methods by declaring them final to prevent them being overridden in subclasses, but the same rules about which method is called apply. The reason to simplify the language (in comparison to C++) - the rules about which method are called are much simpler and easy to remember.
- MichaelGG 13y agoSimpler? The only case it matters is when a subclass has shadowed a non-virtual method. "Simpler" would be simply disallowing shadowing.
- AndrewBissell 13y agoNot having to think about the question "should I make this method virtual?" makes the Java language simpler, yes. In the vast majority of cases where a virtual function call is actually monomorphic or bimorphic at runtime, the JVM JIT can observe that and potentially inline the method (with an if statement in the bimorphic case). It puts guards around the inlined method and deoptimizes in the event that a newly loaded class renders the optimization incorrect.
- MichaelGG 13y agoIt just flips it for "should I make this method final?" So at best it's a wash. In the majority of cases, a function shouldn't be virtual so users need to mark it final to accurately represent their design.
- AndrewBissell 13y agoWell, the answer to "should I make x final" is always "yes" in Java, so you don't really have to think too hard about that either. :-) `final` really should have been the default setting for all methods, classes, and local variables, but unfortunately inheritance was still in vogue when Java was created, and the benefits of immutable values weren't as well understood or appreciated either (or maybe they just figured the C & C++ programmers they were trying to win over would hate it).
- kasey_junk 13y agoAlso depending on the JVM and JIT settings over time those virtual methods get treated as non-virtual.
- CmonDev 13y agoThere you go - something else to fix before other optimizations: "your architecture is enormous and complicated".
- andor 13y agoThe Java Hotspot VM can still optimize for this case, if the virtual call leads to only a few classes most of the time. Several virtual methods can be inlined, but of course there's still an extra step compared to static dispatch: the classes of the current object and the inlined methods have to be compared. If no matching method is inlined, control needs to be passed back to the VM.
- pmjordan 13y agoA fascinating article on this type of optimisation: http://www.azulsystems.com/blog/cliff/2010-04-08-inline-caches-and-call-site-optimization http://www.azulsystems.com/blog/cliff/2010-04-08-inline-cach...
- MrBuddyCasino 13y agoInteresting read, I didn't know that making fields final in Java does nothing for performance. Any idea what those "Generic Popular Frameworks" are? I put my money on Hibernate.
- army 13y agoThis is less of a problem for systems with JIT compilation (including Java, C#, etc). They can recompile the code at runtime, which allows some nice tricks for virtual calls. They can turn a virtual call into a regular call with inline caching (http://en.wikipedia.org/wiki/Inline_caching http://en.wikipedia.org/wiki/Inline_caching), or can even compile a specialized version of the code for a given type and inline the entire virtual function.
- kevingadd 13y agoThe .NET and Java VMs are in fact able to do some inlining on virtual/interface calls and do other sorts of smart dispatch. So the cost of a virtual method in .NET and Java is not necessarily equivalent to the cost in C++.
- MichaelGG 13y agoI tried a simple example[1] in C#, .NET 4.5, both 32 and 64-bit, just looping and calling an Add method. The adding the keyword virtual increased runtimes > 200%. JVMs might do this, but the CLR's codegen doesn't. An old blog post by one of the CLR engineers[1] states: "We don't inline across virtual calls. The reason for not doing this is that we don't know the final target of the call. We could potentially do better here (for example, if 99% of calls end up in the same target, you can generate code that does a check on the method table of the object the virtual call is going to execute on, if it's not the 99% case, you do a call, else you just execute the inlined code), but unlike the J language, most of the calls in the primary languages we support, are not virtual, so we're not forced to be so aggressive about optimizing this case." I guess things haven't changed. My testing with the CLR indicates that for best performance, you should make sure your IL is already inlined. The CLR does much better with huge function bodies. 1: http://pastebin.com/98c7Bt7f http://pastebin.com/98c7Bt7f 2: http://blogs.msdn.com/b/davidnotario/archive/2004/11/01/250398.aspx http://blogs.msdn.com/b/davidnotario/archive/2004/11/01/2503...
- kevingadd 13y agoThe CLR's inlining for virtual calls is constrained specifically to interfaces, not to all uses of 'virtual', IIRC. (Interfaces are still very much virtual calls, they just don't use the 'virtual' keyword.) See [1] for an example where the CLR fully inlines a virtual call (through an interface, specifically) The call is most definitely virtual (or dynamic if you prefer that term), not statically-dispatched. It just happens to be performed through an interface. I suspect the CLR optimizes this because interfaces are incredibly common (IEnumerable, etc.) [1] http://msdn.microsoft.com/en-us/library/ms973852.aspx http://msdn.microsoft.com/en-us/library/ms973852.aspx