Caching 您应该在哪一点缓存属性的值?

Caching 您应该在哪一点缓存属性的值?,caching,properties,Caching,Properties,我一直想知道何时何地是缓存属性值的最佳时间。。。其中有些看起来很简单,就像下面这个 public DateTime FirstRequest { get { if (this.m_FirstRequest == null) { this.m_FirstRequest = DateTime.Now; } return (DateTime)this.m_FirstRequest; } } private Date

我一直想知道何时何地是缓存属性值的最佳时间。。。其中有些看起来很简单,就像下面这个

public DateTime FirstRequest {
    get {
        if (this.m_FirstRequest == null) {
            this.m_FirstRequest = DateTime.Now;
        }
        return (DateTime)this.m_FirstRequest;
    }
}
private DateTime? m_FirstRequest;
但是一些更复杂的情况呢?

  • 来自数据库的值,但在选择后仍为真
  • 存储在内置缓存中并可能不时过期的值
  • 必须首先计算的值
  • 需要一些时间来初始化的值。0.001s、0.1s、1s、5s
  • 一个已设置的值,但可能会出现其他值并将其设置为null,以标记应重新填充该值
  • 似乎有无限的情况
  • 您认为什么是一个属性不能再照顾自己,而是需要一些东西来填充其价值的点?


    [编辑]


    我看到一些建议说我优化得太早了,等等。但我的问题是什么时候该优化。缓存不是我要问的问题,但是当缓存到了时候,应该由谁来负责呢?

    我认为你需要把你的问题反过来,以免过早地陷入优化的陷阱

    您认为什么时候属性不再需要在每次调用时重新计算,而是使用某种形式的缓存? 值的缓存是一种优化,因此不应作为规范进行。在某些情况下,使用此优化显然是相关的,但在大多数情况下,您应该通过执行适当的工作来获得值,然后在分析并显示需要优化后,尝试对其进行优化,从而使属性每次都能正常工作

    缓存是或不是一个好主意的一些原因: -如果值易于频繁更改,则不要缓存 -如果它从不更改,并且您对它从不更改负责,请执行缓存 -如果您不负责提供值,则不要缓存,因为您依赖于其他人的实现

    有许多其他原因支持或反对缓存值,但对于何时缓存和何时不缓存,肯定没有硬性规定——每种情况都不同

    如果你必须缓存。。。 假设您已经确定某种形式的缓存是一种方式,那么如何执行缓存取决于您正在缓存什么、为什么以及如何向您提供值

    例如,如果它是一个单例对象或时间戳(如您的示例中所示),则设置一次值的简单“is it set?”条件是一种有效的方法(即在构造过程中创建实例)。但是,如果它正在访问数据库,并且数据库告诉您它何时更改,则可以基于脏标记缓存该值,只要数据库值表示它已更改,该脏标记就会变脏。当然,如果没有更改通知,则可能必须在每次调用时刷新值,或者在两次检索之间引入最小等待时间(当然,接受值可能并不总是精确的)

    无论何种情况,你都应该考虑每种方法的利弊,并考虑引用该值的方案。消费者是否总是需要最新的价值,或者他们是否能够应付稍微落后的情况?您是否控制该值的来源?源是否提供更改通知(或者您是否可以让它提供此类通知)?来源的可靠性如何?有许多因素会影响您的方法

    考虑到你给出的场景。。。 同样,假设需要缓存

  • 来自数据库的值,但在选择后仍为真。
    如果保证数据库保留该行为,则可以在第一次请求时轮询该值,然后缓存该值。如果不能保证数据库的行为,可能需要更加小心

  • 存储在内置缓存中的值,可能会不时过期。
    我将使用dirty标志方法,其中缓存不时被标记为dirty,以指示缓存值需要刷新,假设您知道“time to time”是什么时候。如果没有,考虑一个定时器,它指示缓存在一定的时间间隔内是脏的。
  • 必须首先计算的值?
    我会根据价值来判断。即使您认为需要缓存,编译器可能已经对其进行了优化。但是,假设需要缓存,如果计算很长,则在构造期间或通过接口(如
    ISupportInitialize
    )进行计算可能会更好

  • 需要一些时间来初始化的值。0.001s、0.1s、1s、5s???
    我会让属性对此不做任何计算,并实现一个事件来指示值何时更改(在值可能更改的任何情况下,这是一种有用的方法)。初始化完成后,将触发事件,允许使用者获取值。你也应该考虑这可能不适合一个财产;相反,考虑异步方法,例如回调方法。

  • 已设置的值,但可能会出现其他值并将其设置为null,以标记应重新填充该值。
    这只是第2点中讨论的脏标志方法的一个特例


  • 一般来说,您应该先让代码正常工作,然后再进行优化,然后只进行分析所说的对您有帮助的优化。

    我理解您的意思,但我要问的是应该缓存的属性。除非需要,否则我不会缓存任何内容(例如,在数据库中查找不会经常更改的信息)