I noticed today that some new properties had appeared in my intellisense on the System.Type
object for my .NET 4.5 projects. Among these was one called CustomAttributes
.
I was intrigued by this since I previously had understood that GetCustomAttributes
was one of the most expensive reflection calls (DynamicInvoke
and the like aside, of course). As I understand it, every call to GetCustomAttributes
results in calling the constructors for the attributes (and thus a memory allocation). I've often resorted to caching the custom attributes separately to avoid performance bottlenecks when processing large numbers of types and such.
So, I wrote up a test to see if CustomAttributes
was any more performant 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 surprising:
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 discovered that the attribute constructors were not called for iterating CustomAttributes
(which I expected since it looks like it is just reading the metadata). Yet somehow, it was slower than GetCustomAttributes
which calls constructors.
My Question
Personally I think it is more readable to use the new property, but the cost is 1.5x-ish slower performance.
So, what advantage is there, if any, of using CustomAttributes
instead of GetCustomAttributes()
?
I'm assuming the situation where we are simply checking to see if an attribute of some type exists on the clas...not using methods or properties on the instance of the attribute.