缓存或不缓存 - GetCustomAttributes

时间:2009-10-23 08:38:20

标签: c# performance reflection

我目前有一个功能:

public static Attribute GetAttribute(MemberInfo Member, Type AttributeType)
{
    Object[] Attributes = Member.GetCustomAttributes(AttributeType, true);

    if (Attributes.Length > 0)
        return (Attribute)Attributes[0];
    else
        return null;
}

我想知道是否值得将属性上的所有属性缓存到 Attribute = _cache[MemberInfo][Type]字典,

这需要使用GetCustomAttributes而不使用任何类型参数,然后枚举结果。值得吗?

6 个答案:

答案 0 :(得分:18)

如果用这个代替你的方法体,你会得到更好的回报:

return Attribute.GetCustomAttribute(Member, AttributeType,false); // only look in the current member and don't go up the inheritance tree.

如果你真的需要以类型为基础进行缓存:

public static class MyCacheFor<T>
{
    static MyCacheFor()
    {
        // grab the data
        Value = ExtractExpensiveData(typeof(T));
    }

    public static readonly MyExpensiveToExtractData Value;

    private static MyExpensiveToExtractData ExtractExpensiveData(Type type)
    {
        // ...
    }
}

每次击败字典查找。再加上它的线程安全:)

干杯, 弗洛里安

PS:取决于你多久调用一次。我有一些使用反射做大量序列化的情况,真的需要缓存,像往常一样,motus operandi是这样的:

  1. 测试
  2. 调试
  3. 再次测试
  4. CPU配置文件
  5. 记忆简介
  6. 优化
  7. 再次测试
  8. CPU配置文件
  9. MEM Profile 这一点非常重要,因为优化cpu绑定代码肯定会将负担转移到内存

答案 1 :(得分:6)

您可以确定的唯一方法是对其进行分析。如果这听起来像陈词滥调,我很抱歉。但是,一句话是陈词滥调的原因通常是因为它是真的。

缓存该属性实际上使代码更复杂,更容易出错。因此,您可能希望在决定之前考虑这一点 - 您的开发时间。

所以像优化一样,除非必须这样做,否则不要这样做。

根据我的经验(我说的是类似AutoCAD的Windows应用程序,有大量的点击编辑GUI操作和繁重的数字运算),自定义属性的读取永远不会 - 甚至一次 - 性能瓶颈。

答案 2 :(得分:4)

您的问题是过早优化的情况。

您不知道反射类的内部工作原理,因此会对多次调用GetCustomAttributes的性能影响做出假设。该方法本身可以很好地缓存其输出,这意味着您的代码实际上会增加开销而不会提高性能。

保存你的大脑周期,以便思考你已经知道的问题!

答案 3 :(得分:3)

旧问题,但GetCustomAttributes是昂贵/重量级的

如果导致性能问题,使用缓存可能是一个好主意

我链接的文章:(闪避常见性能陷阱以制作快速应用程序)已被删除,但此处链接到存档版本:

https://web.archive.org/web/20150118044646/http://msdn.microsoft.com:80/en-us/magazine/cc163759.aspx

答案 4 :(得分:2)

您确实遇到了性能问题吗?如果没有,那么在你需要它之​​前不要这样做。

根据您使用相同参数调用方法的频率,这可能会有所帮助。如果您只按MemberInfoType组合调用一次,那么它就不会有任何好处。即使你确实缓存它,你也可以快速进行内存消耗。这可能适合您的应用程序。

答案 5 :(得分:2)

我刚刚遇到了GetCustomAttributes成为性能瓶颈的情况。在我的情况下,它在一个包含许多行的数据集中被调用了数十万次,这使问题易于隔离。缓存属性解决了问题。

初步测试导致在现代机器上大约5000次通话时几乎没有显着的性能损失。 (随着数据集大小的增加,它变得非常明显。)

我普遍同意关于过早优化的其他答案,但是,在DB调用的CPU指令范围内,我建议GetCustomAttributes更倾向于后者。