Кэшировать или не кэшировать - GetCustomAttributes - PullRequest
15 голосов
/ 23 октября 2009

У меня сейчас есть функция:

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 ]

18 голосов
/ 23 октября 2009

Вы получите лучшие удары за свои деньги, если вы замените тело вашего метода следующим:

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

Beats словарь поиска каждый раз. Плюс это потокобезопасный:)

Ура, Florian

PS: Зависит от того, как часто вы это называете. У меня были случаи, когда выполнение сериализации с использованием рефлексии действительно вызывало кеширование, как обычно, motus operandi:

  1. запись
  2. Тест
  3. Debug
  4. Тест снова
  5. профиль процессора
  6. Профиль Mem
  7. Оптимизировать
  8. Еще раз проверить
  9. CPU Profile
  10. MEM Profile Это важно, поскольку ваша оптимизация кода, связанного с процессором, непременно перенесет нагрузку на память
6 голосов
/ 23 октября 2009

Единственный способ узнать наверняка, это профилировать его. Мне жаль, если это звучит как клише. Но причина, по которой высказывание является клише, часто заключается в том, что это правда.

Кэширование атрибута фактически делает код более сложным и более подверженным ошибкам. Так что вы можете принять это во внимание - время разработки - прежде чем вы решите.

Так что, как и оптимизация, не делайте этого, если не нужно.

Из моего опыта (я имею в виду AutoCAD-подобное Windows-приложение, с большим количеством операций графического интерфейса с редактированием с помощью щелчков мышью и тяжелым сокращением числа), чтение пользовательского атрибута никогда - ни разу - не влияет на производительность узкое место.

4 голосов
/ 23 октября 2009

Ваш вопрос - случай преждевременной оптимизации.

Вы не знаете внутреннюю работу классов отражения и поэтому делаете предположения о влиянии на производительность многократного вызова GetCustomAttributes. Сам метод может уже кешировать свои выходные данные, а это означает, что ваш код фактически добавит накладные расходы без повышения производительности.

Сохраните свои мозговые циклы, чтобы думать о вещах, которые, как вы уже знаете, являются проблемами!

3 голосов
/ 19 декабря 2013

Старый вопрос, но GetCustomAttributes стоит дорого / тяжело

Хорошая идея - использовать кеш, если он вызывает проблемы с производительностью

Статья, на которую я ссылался: (Dodge Common Pitfalls для создания быстрых приложений) была удалена, но здесь ссылка на архивную версию:

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

2 голосов
/ 18 декабря 2013

У меня только что был сценарий, когда GetCustomAttributes оказался узким местом производительности. В моем случае его вызывали сотни тысяч раз в наборе данных со множеством строк, и это облегчало выявление проблемы. Кэширование атрибутов решило проблему.

Предварительное тестирование привело к едва заметному снижению производительности при 5000 вызовах на современном компьютере. (И это стало заметно заметнее, когда размер набора данных увеличился.)

Я в целом согласен с другими ответами о преждевременной оптимизации, однако, в отношении инструкций процессора для вызова БД, я бы предположил, что GetCustomAttributes будет больше склоняться к последнему.

2 голосов
/ 23 октября 2009

У вас действительно проблемы с производительностью? Если нет, то не делайте этого, пока вам это не понадобится.

Это может помочь в зависимости от того, как часто вы вызываете метод с одинаковыми параметрами. Если вы звоните только один раз за комбинацию MemberInfo, Type, это не принесет пользы Даже если вы кешируете его, вы торгуете скоростью на потребление памяти. Это может быть хорошо для вашего приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...