What's the point of caching a value for a property?

I've always wondered when and where is the best way to cache a property value ... Some of them seem to be pretty simple, like 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 difficult situations?

  • A value that comes from the database but remains valid after you select it.
  • A value that is stored in the built-in cache and may expire from time to time.
  • The value to be calculated first?
  • A value that takes some time to initialize. 0.001 s, 0.1 s, 1 s, 5 s .
  • A value that is set but something else may appear, and set it to null to mark it should be repopulated.
  • ... Seems like limitless situations.

Do you think the property can no longer take care of itself and instead requires something to populate its value?


[EDIT]

I see suggestions that I optimize too early, etc. But my question is when is the time to optimize. Caching everything is not what I'm asking, but when it's time to cache, whose responsibility should it be?

+1


source to share


2 answers


In general, you should run the code first and then optimize it later and then only optimize the profiling that will help you.



+2


source


I think you need to twist your question differently so you don't fall into the optimization trap too early.

When do you think that a property no longer needs to be recalculated per call and instead uses some form of caching?

Value caching is an optimization and therefore should not be performed as normal. There are some cases where it is explicitly necessary to use this optimization, but in most cases you must implement the property to work correctly every time you do the appropriate work to get the value, and then try to optimize it once you have profiled and shown that an optimization is needed.

Some reasons caching is or is not a good idea: - Do not cache if the value is subject to frequent changes - Do cache if it never changes and you are responsible for it without changing - Do not cache if you are not responsible for providing the value as then you are relying on another user's implementation

There are many other reasons against caching a value, but there is certainly no hard and fast rule for caching and caching — every case is different.

If you need to cache ...



Assuming you have defined some form of caching this is the way to go, how you do that caching depends on what you cache, why and how you are given the value.

For example, if it's a singleton or timestamp like in your example, just "is it set?" a condition that sets the value once is a valid approach (which either instantiates at build time). However, if it hits the database and the database tells you when it changes, you can cache the value based on a dirty flag that gets dirty whenever the database value says it has changed. Of course, if you don't have change notifications, you may need to either update the value for each call, or enter a minimum timeout between requests (assuming that this value may not always be accurate, of course).

Regardless of the situation, you should always consider the pros and cons of each approach and consider the scenarios under which the meaning refers. Do consumers always need the very last value, or can they handle a little lag? Are you in control of the source of value? Does the source provide change notice (or can you provide such change notice)? How reliable is the source? There are many factors that can affect your approach.

Considering the scripts you gave ...

Again, assuming caching is necessary.

  • A value that comes from the database but remains valid after you select it.
    If this behavior persists in the database, you can simply poll this value on the first request and then cache it. If you cannot guarantee the behavior of the database, you can be more careful.

  • A value that is stored in the built-in cache and may 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 to be updated, assuming you know when "from time to time". If you don't, consider a timer that indicates that the cache is dirty at regular intervals.

  • Which value should be calculated first?
    I would rate this based on value. Even if you think caching is necessary, the compiler may have already optimized it. However, assuming caching is necessary, if the calculation is long, it might be better at build time or through an interface such as ISupportInitialize

    .

  • A value that takes some time to initialize. 0.001 s, 0.1 s, 1 s, 5 s. I would have a property to not calculate and implement an event that indicates when the value changes (this is a useful approach in any situation where the value might change). Upon completion of initialization, a fire occurs to allow consumers to obtain the value. You should also consider that this may not be the case for the property; instead, consider an asynchronous approach such as a callback method.

  • A value that is set, but something else may appear, and set it to null to mark it should be repopulated.
    This is just a special case of the dirty flag approach discussed in point 2.

+1


source







All Articles