缓存或不缓存 - GetCustomAttributes

Cou*_*y D 16 c# reflection performance

我目前有一个功能:

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;
}
Run Code Online (Sandbox Code Playgroud)

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

这将需要在GetCustomAttributes没有任何类型参数的情况下使用,然后枚举结果.这值得么?

Flo*_*yon 20

如果你用你的方法替换你的方法体,你会得到更好的刘海!

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

如果您确实需要以类型为基础进行缓存:

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)
    {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

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

干杯,弗洛里安

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

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

  • 在这种情况下,让我分享一个技巧:如果你要缓存你的密钥是类型的东西,使用泛型类型而不是哈希表.我更新了上面的代码 (4认同)

Gra*_*ton 6

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

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

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

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


TTT*_*TTT 5

我刚刚遇到过 GetCustomAttributes 成为性能瓶颈的场景。就我而言,它在包含多行的数据集中被调用了数十万次,这使得问题易于隔离。缓存属性解决了这个问题。

初步测试导致在现代机器上大约 5000 次调用时几乎没有明显的性能下降。(随着数据集大小的增加,它变得更加明显。)

我通常同意关于过早优化的其他答案,但是,在 CPU 指令到 DB 调用的规模上,我建议 GetCustomAttributes 更倾向于后者。