9

I'm doing some post-build CIL weaving that adds CIL to all methods in an assembly (in other words tons of methods). Each method checks if a specific value is null. Example (C# Reflector'd version of CIL code):

// CIL woven region start
if (MyType.Something == null) {
 // ... some new stuff
}
// CIL woven region end

What is the performance impact of having MyType.Something as a Property vs. a Field? I know I've read that the C# compiler performs special optimizations and there should be no performance impact in that case...but what about in the case of direct CIL code (no C# compiler)...? Or is it the JIT compiler that allows for these optimizations (so direct CIL code still benefits)?

Will emitting OpCode.Call for the static property's accessor have poorer performance than Ldsfld (bear in mind this is across tens of thousands of invocations since every method in the assembly is woven)?

Thanks.

Jeff
  • 35,755
  • 15
  • 108
  • 220

3 Answers3

13

When developing the math library for SlimDX, we found that, on pre-.NET 3.5 SP1 frameworks, using fields for the members of the math types (such as X, Y, Z for a Vector3) gave a disproportionate performance increase over properties. In other words, the difference was noticeable for small math functions which heavily accessed properties.

This has since been improved since .NET 3.5 SP1 (see JIT inling). While I believe that the JIT prior to that will still inline small methods (properties are simply methods after all), there is a bug in the earlier frameworks that prevented inlining of methods that take or return value types.

Note that the difference, when there, is still quite small. I would still elect to use properties in all but the most performance critical cases.

MikeP
  • 7,829
  • 33
  • 34
  • Ok thanks. We are using 3.5 SP1. Just curious, since the code is CIL and only visible post build, what is your rationale for still using properties? – Jeff Dec 06 '10 at 18:21
  • In your case I don't know that I'd use a property. Generally the rational behind properties is robustness from a library design and maintenance point of view, but that doesn't seem to apply here. – MikeP Dec 06 '10 at 20:56
  • I removed the `{ get; protected set; }` in my Barnes-Hut quadtree from the `Parent` and `Child` properties, and got a free 25% performance increase in my gravity simulator in .NET 5.0, after noticing them showing up in the Top Functions list by Self CPU of Performance Profiler. – Elaskanator Jan 10 '22 at 06:19
5

The C# compiler won't optimize this, no - but the JIT compiler can usually inline trivial (and non-virtual) properties as far as I'm aware.

As with all performance questions though: when in doubt, test!

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I'm not sure how to test without suffering the "observer" effect, so I was hoping someone might know off hand. – Jeff Dec 06 '10 at 18:08
  • 2
    @JeffN825: I'd argue that if you can apply the test in real-world code and not be able to observe any difference, then that's good enough evidence that any difference is insignificant :) – Jon Skeet Dec 06 '10 at 18:35
2

The effect is minor in either direction. If your properties look like this::

public static SomeType PropertyName
{
    get {return MyType.propertyName;}
    set {MyType.propertyName = value;}
}

There genuinely should be a very minor difference. The Jit compiler should inline the call MyType.set_Property into a field load, but even if it couldn't due to a bug. I'd personally err on the side of caution and stick with the property setters and getters as potentially the method body might change, and as a result the raw field access/mutation may not be enough.

If you'd like to test you can force the method you emit to use the MethodImpl that turns off inlining or optimizing. And then compare the difference, I really doubt it'll be significant.

Michael B
  • 7,512
  • 3
  • 31
  • 57