Benefit of using CustomAttributes vs GetCustomAttributes ()

Today I noticed that some new properties appeared in my intellisense in the System.Type object for my .NET 4.5 projects. Among them was one called CustomAttributes .

I was intrigued by this, as I previously realized that GetCustomAttributes was one of the most expensive reflection calls ( DynamicInvoke and the like aside, of course). As far as I understand, every call to GetCustomAttributes leads to a call to the constructors for the attributes (and, consequently, to memory allocation). I often resorted to caching individual attributes separately to avoid performance bottlenecks when handling a large number of types, etc.

So, I wrote a test to check if CustomAttributes more efficient than GetCustomAttributes :

 static void Main(string[] args) { var sw = Stopwatch.StartNew(); Debug.WriteLine(typeof(Attributed).GetType()); for (int i = 0; i < 10000; i++) { var attrs = typeof(Attributed) .CustomAttributes .Select(a => a.AttributeType) .ToList(); } sw.Stop(); Debug.WriteLine("Using .NET 4.5 CustomAttributes property: {0}", sw.Elapsed); sw = Stopwatch.StartNew(); for (int i = 0; i < 10000; i++) { var attrs = typeof(Attributed) .GetCustomAttributes(true) .Select(a => a.GetType()) .ToList(); } sw.Stop(); Debug.WriteLine("Using GetCustomAttributes method: {0}", sw.Elapsed); } 

With some test classes:

 [Dummy] [Dummy] [Dummy] [Dummy] [Dummy] [Dummy] class Attributed { } [AttributeUsage(AttributeTargets.Class, AllowMultiple=true)] class DummyAttribute : Attribute { public DummyAttribute() { } } 

The results were unexpected:

 System.RuntimeType Using .NET 4.5 CustomAttributes property: 00:00:00.1351259 Using GetCustomAttributes method: 00:00:00.0803161 

The new CustomAttributes property was actually slower than the existing GetCustomAttributes method!

Debugging further, I found that attribute constructors were not called to iterate CustomAttributes (which I expected, since it looks like it's just reading metadata). However, it was slower than GetCustomAttributes , which calls constructors.

My question

Personally, I think that the use of a new property is more readable, but the cost is 1.5 times less than performance.

So, what advantage, if any, is to use CustomAttributes instead of GetCustomAttributes() ?

I assume that we are simply checking to see if any attribute of some type exists in the class ... without using the methods or properties of the attribute instance.

+5
source share
1 answer

You are making a traditional benchmarking error that makes many .NET programmers think Reflection is slow. Slower than it really is. Reflection is very lazy, you do not pay for it when you do not use it. What your first measurement does is include the entire cost of page failure in metadata in RAM and setting up a cache for displaying type information. This cost is not included in the second dimension, which makes GetCustomAttributes () better than it really is.

Always include a loop around the reference code, run it 10 times. Now you will see that the CustomAttributes property is actually slow, I measure it (approximately) at 0.083 versus 0.063 seconds, 30% slower.

The CustomAttributes property must be added to .NET 4.5 to support language projection for WinRT. You cannot use GetCustomAttributes () in a Store, Phone, or PCL project. WinRT's reflection is very different, a COM-based API is an unavoidable side effect. The implementation code is enough for someone to clear their eyes, but the general scheme is that the property is implemented in C #, and the method is implemented in the CLR environment. C # code should do more work to handle the details of the projection of the language, so it is inevitably slower.

So just use GetCustomAttributes (), use the property when you need to. The difference in speed by 30% is not a serious reason for compromising the style and readability, use common sense.

+10
source

All Articles