我今天注意到在我的.NET 4.5项目中,
结果令人惊讶:
新的CustomAttributes属性比现有的GetCustomAttributes方法还要慢!进一步调试后,我发现迭代CustomAttributes时并未调用属性构造函数(我原本以为这只是在读取元数据)。但出乎意料的是,它比调用构造函数的GetCustomAttributes方法还要慢。
我的问题是:个人认为使用新属性更易读,但代价是1.5倍左右的性能下降。那么,相较于GetCustomAttributes(),使用CustomAttributes是否有任何优势呢?我假设我们仅检查某种类型的属性是否存在于类上...不使用属性实例的方法或属性。
System.Type
对象的智能感知中出现了一些新属性,其中之一叫做CustomAttributes
。我对此很感兴趣,因为我以前曾经了解过GetCustomAttributes
是最昂贵的反射调用之一(当然除了DynamicInvoke
等)。据我所知,每次调用GetCustomAttributes
都会导致调用属性的构造函数(从而进行内存分配)。我经常单独缓存自定义属性,以避免处理大量类型时的性能瓶颈。
因此,我编写了一个测试,以查看CustomAttributes
是否比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);
}
有一些测试类:
[Dummy]
[Dummy]
[Dummy]
[Dummy]
[Dummy]
[Dummy]
class Attributed
{
}
[AttributeUsage(AttributeTargets.Class, AllowMultiple=true)]
class DummyAttribute : Attribute
{
public DummyAttribute()
{
}
}
结果令人惊讶:
System.RuntimeType
Using .NET 4.5 CustomAttributes property: 00:00:00.1351259
Using GetCustomAttributes method: 00:00:00.0803161
新的CustomAttributes属性比现有的GetCustomAttributes方法还要慢!进一步调试后,我发现迭代CustomAttributes时并未调用属性构造函数(我原本以为这只是在读取元数据)。但出乎意料的是,它比调用构造函数的GetCustomAttributes方法还要慢。
我的问题是:个人认为使用新属性更易读,但代价是1.5倍左右的性能下降。那么,相较于GetCustomAttributes(),使用CustomAttributes是否有任何优势呢?我假设我们仅检查某种类型的属性是否存在于类上...不使用属性实例的方法或属性。
GetCustomAttributes
也需要这样做,所以我本来期望它会快得多。也许获取ConstructorInfo
和其他信息的过程比我想象中的更昂贵? - Los Frijoles