【发布时间】:2015-08-18 09:58:02
【问题描述】:
我今天注意到一些新属性出现在我的智能感知中,用于我的 .NET 4.5 项目的 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 倍。
那么,如果有的话,使用CustomAttributes 代替GetCustomAttributes() 有什么好处?
我假设我们只是检查类中是否存在某种类型的属性...而不是使用属性实例上的方法或属性。
【问题讨论】:
-
考虑到基准的简单性,这只是一个微小的差异。这可能只是在误差范围内被丢弃。你比较过这些 API 的实际实现吗?
-
是的,这是一个非常小的差异,但是当增加迭代次数时它确实可以扩展并保持 1.5 倍的比率,这意味着当使用自定义迭代大量事物时它可能会产生影响属性。我正在尝试找到一个程序集来指向 ILSpy 以查看实现(除非我可以在他们首先在线的参考源中找到它)
-
老实说,我更感兴趣的是它为什么变慢。我本来预计它会明显更快,因为它只是读出
GetCustomAttributes无论如何都需要做的类型的元数据。也许获得ConstructorInfo和其他东西的过程比我想象的要贵?
标签: c# .net reflection custom-attributes