开发者

To cache or not to cache - GetCustomAttributes

开发者 https://www.devze.com 2022-12-09 11:57 出处:网络
I currently have a function: public static Attribute GetAttribute(MemberInfo Member, Type AttributeType)

I currently have a function:

public static Attribute GetAttribute(MemberInfo Member, Type AttributeType)
{
    Objec开发者_开发问答t[] Attributes = Member.GetCustomAttributes(AttributeType, true);

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

I am wondering if it would be worthwhile caching all the attributes on a property into a Attribute = _cache[MemberInfo][Type] dictionary,

This would require using GetCustomAttributes without any type parameter then enumerating over the result. Is it worth it?


You will get better bangs for your bucks if you replace the body of your method with this:

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

If you really need to cache on a type-basis:

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)
    {
        // ...
    }
}

Beats dictionary lookups everytime. Plus it's threadsafe:)

Cheers, Florian

PS: Depends how often you call this. I had some cases where doing a lot of serialization using reflection really called for caching, as usual, you want to measure the performance gain versus the memory usage increase. Instrument your memory use and profile your CPU time.


The only way you can know for sure, is to profile it. I am sorry if this sounds like a cliche. But the reason why a saying is a cliche is often because it's true.

Caching the attribute is actually making the code more complex, and more error prone. So you might want to take this into account-- your development time-- before you decide.

So like optimization, don't do it unless you have to.

From my experience ( I am talking about AutoCAD-like Windows Application, with a lot of click-edit GUI operations and heavy number crunching), the reading of custom attribute is never--even once-- the performance bottleneck.


I just had a scenario where GetCustomAttributes turned out to be the performance bottleneck. In my case it was getting called hundreds of thousands of times in a dataset with many rows and this made the problem easy to isolate. Caching the attributes solved the problem.

Preliminary testing led to a barely noticeable performance hit at about 5000 calls on a modern day machine. (And it became drastically more noticeable as the dataset size increased.)

I generally agree with the other answers about premature optimization, however, on a scale of CPU instruction to DB call, I'd suggest that GetCustomAttributes would lean more towards the latter.


Your question is a case of premature optimization.

You don't know the inner workings of the reflection classes and therefore are making assumptions about the performance implications of calling GetCustomAttributes multiple times. The method itself could well cache its output already, meaning your code would actually add overhead with no performance improvement.

Save your brain cycles for thinking about things which you already know are problems!


Old question but GetCustomAttributes is costly/heavyweight

Using a cache if it is causing performance problems can be a good idea

The article I linked: (Dodge Common Performance Pitfalls to Craft Speedy Applications) was taken down but here a link to an archived version:

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


Are you actually having a performance problem? If not then don't do it until you need it.

It might help depending on how often you call the method with the same paramters. If you only call it once per MemberInfo, Type combination then it won't do any good. Even if you do cache it you are trading speed for memory consumption. That might be fine for your application.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号