Practical ASP.NET
Faster Applications with Caching
The ASP.NET Cache object could be the secret to speeding up your application if you just started using it more.
I'm a big fan of ASP.NET's Cache object. I mentioned the Cache once before
as part of a
longer
article on optimizing ASP.NET applications but I always felt that I shortchanged
the topic. The Cache is your best tool for improving performance.
In optimizing application, there's no unalloyed good; everything costs something.
You never make an application purely "better." Instead, you juggle
trade-offs, giving up something you have lots of to get something you want more
of. You'll often get your biggest gains by trading disk access for memory access.
The benefits of this trade-off are driven by two facts: the slowest thing you
can do in data processing is access your database server; the fastest thing
you can do is pull something from memory. To reduce your calls to the database
server, you can hold more data in memory by trading off something you have lots
of (memory) for something you need (faster processing).
Why the Cache Is Your Best Friend
And you do have lots of memory -- but only most of the time: Most Web
servers are sized to handle their peak volumes. By definition, you're only at
your peak volume for a short period of time every day. So, most of the time,
you have excess memory.
The Cache object does something wonderful: If you have excess memory available,
the Cache will hold objects in memory. If you don't have excess memory available,
the Cache discards some of its contents and frees up the memory you need for
your peak period.
But it gets better. When the Cache starts discarding objects, it prefers to
discard the objects that haven't been used for the longest period of time. This
means that as memory gets tight, the objects that are being used stay in memory
while the objects that aren't being used are discarded.
Using the Cache Correctly
So, how should you use the Cache? First, assume that the thing you need is in
the Cache. So write your code to retrieve the item from the Cache. You might
be retrieving a custom business object (e.g., a Customer object encapsulating
Customer data) or a DataSet filled with data from your database.
After you've retrieved the item from the Cache, check to see if you actually
got it. If you did, congratulations! You just replaced a trip to the database
(the slowest thing you can do) with retrieving something from memory (the fastest
thing you can do). If you don't find the item you wanted, go and get it from
the database as you would have to do without the Cache. Now put the item in
the Cache for next time.
The code looks like this:
Dim ds As DataSet
ds = Cache("MyDataSet")
If ds Is Nothing Then
...code to fill the dataset...
Cache.Insert("MyDataSet", ds)
End If
What will happen next? If you're short on memory, the item will be discarded
as soon as you add it. If you have excess memory, the item will wait in the
Cache until you need it again. If, later on, you run short on memory and your
item is being used, it will stay in memory while objects that aren't being used
are discarded. If your item is discarded, it stays out until your code needs
to retrieve it again.
The result? You use all of the memory available to you at any time and ensure
that excess memory is devoted to the objects that your application needs right
now.
One note: The order of operations that I used in the sample code is critical.
Some developers check to see if the item is in the Cache and, if it's present,
retrieve the item. This is fatal because between the check and the retrieval,
the item could be discarded. Always -- as I did here -- retrieve the item first.
If it's not in the Cache, you'll just get a null reference back.
About the Author
Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.