0

Consider the following alternative implementations that derived, internal classes are intended to override, returning true:

public virtual bool IsInternal => false;

...and...

public virtual bool IsInternal() => false;

What is the difference memory- and performance-wise?

Can the compiler detect the static results and, when optimizing/inlining, use them instead of saving the property value for each instance or invoking the function? Can these virtual members be inlined by the compiler at all and what would the impact be?

mike
  • 1,627
  • 1
  • 14
  • 37
  • Why are you asking? What is the context of your question? Why does the answer matter to you? – mjwills Sep 03 '19 at 23:47
  • Of your two solutions, the first is a read-only property (without a backing field) and the second is a function. The property (in the style you have written it) is basically the same function under the hood. So I'd expect them in most cases to perform basically the same. – mjwills Sep 03 '19 at 23:49

1 Answers1

4

What is the difference memory- and performance-wise?

None, they both compile to virtual methods (C# properties are just a different syntax for getter+setter methods).

Each virtual member adds to a type's vtable size (this is negligible though, as vtables are per-type, not per-instance).

Performance wise, a virtual-call is a couple of instructions more expensive and also requires more memory-accesses, but a good CPU, with modern branch prediction and large caches minimize the impact. If you really care about performance to that level you won't be using the CLR anyway - as far as most developers should be concerned virtual calls cost the same as non-virtual calls.

Can the compiler detect the static results and, when optimizing/inlining, use them instead of saving the property value for each instance or invoking the function?

  • The CLR in .NET Framework 1.0, 1.1, 2.0 and 4.0 does not (to my knowledge). The C# compiler may replace a virtual call with a non-virtual call in compiled CIL in certain trivial cases (e.g. (new BaseVirtualType().VirtualMethod())), but the JIT doesn't make that optimization (but the JIT might then inline it, but I don't know for certain). The C# compiler may also inline when optimizations are enabled.

  • The CLR in .NET Core 2.0 does some de-virtualization, according to the spec-doc for .NET Core 3.0 (see below).

  • The CLR in .NET Core 3.0 will be more aggressive, here'st heir spec-doc: https://github.com/dotnet/coreclr/blob/master/Documentation/design-docs/GuardedDevirtualization.md

Dai
  • 141,631
  • 28
  • 261
  • 374
  • 1
    Just to clarify the above, the C# compiler never inlines anything. As of .Net Core 2.0 and .Net Framework 4.7.2 the JIT can sometimes devirtualize and if that succeeds, inline. Guarded Devirtualization is still an experimental feature and is not enabled. We may find a way to turn it on in .Net 5 -- jury is still out on this. – Andy Ayers Sep 11 '19 at 16:06
  • @AndyAyers has the jury reached a verdict? – Qwertie Apr 06 '22 at 14:55
  • Yes, though it didn't get enabled until .Net 6. See for instance https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-6/ . – Andy Ayers Apr 09 '22 at 02:44