Какой момент вы должны кэшировать значение для свойства? - PullRequest
1 голос
/ 04 декабря 2008

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

public DateTime FirstRequest {
    get {
        if (this.m_FirstRequest == null) {
            this.m_FirstRequest = DateTime.Now;
        }
        return (DateTime)this.m_FirstRequest;
    }
}
private DateTime? m_FirstRequest;

А как насчет более сложных ситуаций?

  1. Значение, которое поступает из базы данных, но остается истинным после его выбора.
  2. Значение, которое хранится во встроенном кэше и может время от времени истекать.
  3. Значение, которое должно быть рассчитано первым?
  4. Значение, которое требуется некоторое время для инициализации. 0,001 с, 0,1 с, 1 с, 5 с ???
  5. Значение, которое установлено, но что-то еще может прийти и установить его в null, чтобы указать, что оно должно быть повторно заполнено.
  6. ??? Кажется, что есть безграничные ситуации.

Как вы думаете, в чем смысл того, что свойство больше не может заботиться о себе и вместо этого требует, чтобы что-то заполнило его значение?


[EDIT]

Я вижу предложения, которые я оптимизирую слишком рано и т. Д. Но мой вопрос - когда пора оптимизировать. Кэширование всего не то, о чем я спрашиваю, но когда пришло время кешировать, чья это ответственность?

Ответы [ 2 ]

2 голосов
/ 04 декабря 2008

В общем, сначала вы должны заставить работать код, а затем оптимизировать, а затем выполнять только те оптимизации, которые, по словам профилирования, помогут вам.

1 голос
/ 04 декабря 2008

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

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

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

Некоторые причины, по которым кэширование является или не является хорошей идеей: - Не кэшируйте, если значение подвержено частым изменениям - Делайте кеш, если он никогда не меняется, и вы отвечаете за то, чтобы он никогда не менялся - Не кешируйте, если вы не несете ответственности за предоставление значения, поскольку вы полагаетесь на чью-либо реализацию

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

Если вам нужно кешировать ...

Предполагая, что вы определили, что какой-то вид кэширования - это путь, то как вы его выполняете, зависит от того, что вы кэшируете, почему и как вам предоставляется значение.

Например, если это одноэлементный объект или временная метка, как в вашем примере, просто "установлено ли это?" Условие, которое устанавливает значение один раз, является допустимым подходом (это или создание экземпляра во время построения). Однако, если он попадает в базу данных и база данных сообщает вам, когда она изменяется, вы можете кэшировать значение на основе грязного флага, который становится грязным всякий раз, когда значение базы данных говорит, что оно изменилось. Конечно, если у вас нет уведомлений об изменениях, вам, возможно, придется либо обновлять значение при каждом вызове, либо вводить минимальное время ожидания между поисками (конечно, принимая, что значение может не всегда быть точным).

Независимо от ситуации, вы всегда должны учитывать плюсы и минусы каждого подхода и рассматривать сценарии, в которых указано значение. Потребителям всегда нужна самая свежая ценность или они могут справиться с отставанием? Вы контролируете источник стоимости? Предоставляет ли источник уведомления об изменениях (или вы можете сделать так, чтобы он предоставлял такие уведомления)? Какова надежность источника? Есть много факторов, которые могут повлиять на ваш подход.

Учитывая сценарии, которые вы дали ...

Опять же, при условии, что кеширование необходимо.

  1. Значение, которое поступает из базы данных, но остается истинным после его выбора.
    Если база данных гарантированно сохранит такое поведение, вы можете просто опросить значение при первом запросе и затем кэшировать его. Если вы не можете гарантировать поведение базы данных, вы можете быть осторожнее.

  2. Значение, которое хранится во встроенном кэше и может время от времени истекать.
    Я бы использовал подход «грязный флаг», когда время от времени кэш помечается как «грязный», чтобы указать, что кэшированное значение нуждается в обновлении, если вы знаете, когда «время от времени». Если вы этого не сделаете, рассмотрите таймер, который показывает, что кэш регулярно очищается.

  3. Значение, которое должно быть вычислено первым?
    Я бы оценил это исходя из ценности. Даже если вы считаете, что кэширование необходимо, компилятор, возможно, уже оптимизировал его. Однако при условии, что кэширование необходимо, если вычисление занимает много времени, оно может быть лучше во время построения или через интерфейс, такой как ISupportInitialize.

  4. Значение, для инициализации которого требуется некоторое время. 0,001 с, 0,1 с, 1 с, 5 с ???
    Я бы сделал так, чтобы свойство не делало вычисления для этого и реализовывало событие, которое указывает, когда значение изменяется (это полезный подход в любой ситуации, когда значение может измениться). После завершения инициализации происходит событие, позволяющее потребителям получить значение. Вам также следует учитывать, что это может не подходить для собственности; Вместо этого рассмотрим асинхронный подход, такой как метод с обратным вызовом.

  5. Значение, которое установлено, но может прийти что-то еще и установить его в null, чтобы указать, что оно должно быть повторно заполнено.
    Это всего лишь частный случай подхода «грязного флага», рассмотренного в пункте 2.

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