简体   繁体   English

您应该在什么时候缓存属性值?

[英]What point should you cache a value for a Property?

I've always wondered about when and where is the best time to cache a property value... Some of them seem pretty simple, like the one below... 我一直想知道何时何地缓存属性值的最佳时间...其中一些似乎很简单,例如下面的那个...

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

But what about some more complicated situations? 但是,一些更复杂的情况呢?

  1. A value that comes from a database, but remains true after it's been selected. 来自数据库的值,但是在被选择后仍然为真。
  2. A value that is stored in a built-in cache and might expire from time to time. 存储在内置缓存中的值,该值可能会不时过期。
  3. A value that has to be calculated first? 必须先计算一个值?
  4. A value that requires some time to initialize. 需要一些时间来初始化的值。 0.001s, 0.1s, 1s, 5s ??? 0.001s,0.1s,1s, 5s ???
  5. A value that is set, but something else may come and set it to null to flag that it should be repopulated. 已设置的值,但可能会出现其他情况,并将其设置为null,以指示应重新填充该值。
  6. ??? ??? There seems to be limitless situations. 似乎有无限的情况。

What do you think is the point that a property can no longer take care of itself and instead require something to populate its value? 您认为财产不再能照顾自己,而是需要某种东西来填充其价值,这是什么意思?


[EDIT] [编辑]

I see suggestions that I'm optimizing too early, etc. But my question is for when it is time to optimize. 我看到过早优化的建议,等等。但是我的问题是何时该进行优化。 Caching everything isn't what I'm asking, but when it is time to cache, whose responsibility should it be? 缓存所有内容不是我要的,而是何时该缓存,应该由谁负责?

通常,您应该先使代码工作,然后再进行优化,然后再进行性能分析认为可以帮助您的优化。

I think you need to turn your question the other way around lest you fall into a trap of optimizing too early. 我认为您需要反过来提出您的问题,以免您陷入过早优化的陷阱。

When do you think is the point that a property no longer needs recalculating on every call and instead uses some form of caching? 您认为什么时候不再需要在每次调用时重新计算属性而是使用某种形式的缓存的意义?

The caching of a value is an optimization and should therefore not be done as the norm. 值的缓存是一种优化,因此不应作为规范。 There are some cases where it is clearly relevant to use this optimization but in most cases, you should implement the property to work correctly every time by doing the appropriate work to get the value and then look to optimize it once you've profiled and shown that optimization is required. 在某些情况下,使用此优化显然很重要,但是在大多数情况下,应该通过进行适当的工作来获取该值,然后在分析和显示该值后对其进行优化,以使属性每次都能正确运行需要优化。

Some reasons why caching is or is not a good idea: - Don't cache if the value is prone to frequent change - Do cache if it never changes and you are responsible for it never changing - Don't cache if you are not responsible for providing the value as you're then relying on someone else's implementation 缓存是不是一个好主意的一些原因:-如果值易于频繁更改,则不要缓存-如果值永不更改且您负责它永不更改,请缓存;-如果不负责则不要缓存在您依赖他人的实现时提供价值

There are many other reasons for and against caching a value but there is certainly no hard and fast rule on when to cache and when not to cache - each case is different. 支持和反对缓存值还有很多其他原因,但是对于何时缓存和何时不缓存没有明确的硬性规定-每种情况都是不同的。

If you have to cache... 如果您必须缓存...

Assuming that you've determined some form of caching is the way to go, then how you perform that caching depends on what you are caching, why, and how the value is provided to you. 假设您已确定要使用某种形式的缓存,那么如何执行该缓存取决于您要缓存的内容,原因以及为您提供值的方式。

For example, if it is a singleton object or a timestamp as in your example, a simple "is it set?" 例如,如果像您的示例中那样是单例对象或时间戳记,则简单的“是否已设置?” condition that sets the value once is a valid approach (that or create the instance during construction). 一次设置值的条件是一种有效方法(即在构造过程中创建实例)。 However, if it's hitting a database and the database tells you when it changes, you could cache the value based on a dirty flag that gets dirtied whenever the database value says it has changed. 但是,如果它正在命中数据库,并且数据库会在更改时通知您,则可以基于脏标志来缓存该值,该脏标志每当数据库值更改时就会弄脏。 Of course, if you have no notification of changes, then you may have to either refresh the value on every call, or introduce a minimum wait time between retrievals (accepting that the value may not always be exact, of course). 当然,如果您没有更改通知,则可能必须在每次调用时刷新值,或在两次检索之间引入最短等待时间(当然,接受值不一定总是准确的)。

Whatever the situation, you should always consider the pros and cons of each approach and consider the scenarios under which the value is referenced. 无论情况如何,您都应始终考虑每种方法的利弊,并考虑引用该值的方案。 Do the consumers always need the most recent value or can they cope with being slightly behind? 消费者是否总是需要最新的价值,或者他们可以应付落后的情况? Are you in control of the value's source? 您控制价值来源吗? Does the source provide notification of changes (or can you make it provide such notifications)? 源是否提供更改通知(或者您可以使其提供此类通知)? What is the reliability of the source? 来源的可靠性如何? There are many factors that can affect your approach. 有很多因素会影响您的方法。

Considering the scenarios you gave... 考虑到您给出的方案...

Again, assuming that caching is needed. 同样,假设需要缓存。

  1. A value that comes from a database, but remains true after it's been selected. 来自数据库的值,但是在被选择后仍然为真。
    If the database is guaranteed to retain that behavior, you can just poll the value the first time it is requested and cache it thereafter. 如果保证数据库保留该行为,则可以在第一次请求该值时对其进行轮询,然后将其缓存。 If you can't guarantee the behavior of the database, you may want to be more careful. 如果不能保证数据库的行为,则可能需要格外小心。

  2. A value that is stored in a built-in cache and might expire from time to time. 存储在内置缓存中的值,该值可能会不时过期。
    I would use a dirty flag approach where the cache is marked dirty from time to time to indicate that the cached value needs refreshing, assuming that you know when "time to time" is. 我将使用脏标志方法,其中不时将高速缓存标记为脏,以指示需要刷新刷新的值(假设您知道“时间”)。 If you don't, consider a timer that indicates the cache is dirty at regular intervals. 如果不这样做,请考虑使用一个计时器,该计时器指示缓存定期刷新。

  3. A value that has to be calculated first? 必须先计算一个值?
    I would judge this based on the value. 我会根据价值来判断。 Even if you think caching is needed, the compiler may have optimised it already. 即使您认为需要缓存,编译器也可能已经对其进行了优化。 However, assuming caching is needed, if the calculation is lengthy, it might be better during construction or via an interface such as ISupportInitialize . 但是,假设需要缓存,如果计算时间较长,则在构建过程中或通过ISupportInitialize的接口可能会更好。

  4. A value that requires some time to initialize. 需要一些时间来初始化的值。 0.001s, 0.1s, 1s, 5s??? 0.001s,0.1s,1s,5s ???
    I'd have the property do no calculation for this and implement an event that indicates when the value changes (this is a useful approach in any situation where the value might change). 我希望该属性对此不做任何计算,并实现一个指示值何时更改的事件(这在值可能更改的任何情况下都是有用的方法)。 Once the initialization is complete, the event fires, allowing consumers to get the value. 初始化完成后,将触发该事件,从而使消费者获得价值。 You should also consider that this might not be suited for a property; 您还应该考虑这可能不适合物业; instead, consider an asynchronous approach such as a method with a callback. 相反,请考虑使用异步方法,例如带有回调的方法。

  5. A value that is set, but something else may come and set it to null to flag that it should be repopulated. 已设置的值,但可能会出现其他情况,并将其设置为null,以指示应重新填充该值。
    This is just a special case of the dirty flag approach discussed in point 2. 这只是第2点中讨论的脏标志方法的特例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM