Being computer science expert, I can visualize the load on Processor when I write the code, and though its cumbersome sometime to write more code to perform optimized operation,but its real worth while to spend time to understand Caching in programming.
Static Caching Config Values
The configuration values that you probably store in some config file, or some xml, or some registry etc should be statically cached in any class. For example, you need to access "AppConnectionString" defined in web.config or app.config, if you use expression
WebConfigurationManager.ConnectionStrings["AppConnectionString"]
every time then it would be very costly as first it tries to get instance of config file, then the section and then once again the HashTable of probably NamedValueCollection type and so on. This all is very costly for any value that is stored in config file and which stays unchanged for months or even years. I would always access it in a static class like this.
private static string _AppConnectionString = null; public static string AppConnectionString { if(_AppConnectionString == null) { _AppConnectionString = WebConfigurationManager .ConnectionStrings["AppConnectionString"] .ConnectionString; } return _AppConnectionString; }
Property Cache in Local Variable
Consider following code
void DrawEffectRectangle(Rectangle r) { for(int i=50; i>=0;i--) { SetColor(i*5); Draw3dRect(r.Left - i, r.Top - i, r.Right + i, r.Bottom + i); } }
This method uses 4 properties, Left, Top, Right and Bottom, now consider following effective code which produces exactly same effect.
void DrawEffectRectangle(Rectangle r) { int left = r.Left; int top = r.Top; int bottom = r.Bottom; int right = r.Right; for(int i=50; i>=0;i--) { SetColor(i*5); Draw3dRect(left - i, top - i, right + i, bottom + i); } }
Now note, the calls to property evaluation has been reduced, lets assume one property access code takes 1ms then this code will execute 446ms times faster then the earlier code.
Note, you should use this technique carefully after examining that the value of these property evaluations are constant throughout the execution.
Cache Before Loop
Assuming following code,
for(int i=0;i<Results.Length;i++) { ProcessResult(Results[i]); }
Now here as well, expression i<Results.Length gets evaluated Results.Length times, assuming it to be an array. But consider the following code,
int len = Results.Length; for(int i=0;i<len;i++) { ProcessResult(Results[i]); }
Caching once again the Length in a local variable reduces Property Evaluation code.
QueryString Caching
Most of the time, we have habbit of using ‘Request.QueryString["SomeID"]‘ this is very bad if you keep on calling this way, you must cache this in beginning of Page processing that will significantly improve your Web Server Performance. I would use following way to initialize my QueryString based Page variables.
private T GetQueryStringValue<T>(string name, T def) { object val = Request.QueryString[name]; if(val == null) return def; return (T)Converter.ChangeType(typeof(T),val); } private long CustomerID = 0; private string Process = ""; private void Page_Load(object sender, EventArgs e) { CustomerID = GetQueryStringValue<long>("CustomerID", 0); Process = GetQueryStringValue<string>("Process", "Signup"); }
And then using the values of CustomerID and Process variables rather then accessing Request.QueryString object again and again. There are two advantages in it, first, you can avoid Request.QueryString calls, and second you can compare native type comparisons to evaluate your algorithm flow. And you can see yourself after decompiling Request object through Reflector, that each access of Request.QueryString and its indexer basically requires more then 20-80 steps to get final result. Sure processor has 3 GHz but that doesnt mean that 1000 requests can just waste so many cpu cycles and finally frustrating the end user who is waiting expecting some result !!
Session Variable Caching
I would also try to cache, session variable in local page class as defined following,
private long _SessionWebUserID = -1; private long SessionWebUserID{ get{ if(_SessionWebUserID == -1) { _SessionWebUserID = 0; object val = Session["WebUserID"]; if(val != null) { _SessionWebUserID = (long)val; } } return _SessionWebUserID; } }
Sure this method has additional _SessionWebUserID != -1 comparison everytime you access the property, but belive me, its far less costly then accessing Session NamedValueCollection again and again.
However the drawback is, if you cache session variable for longer period then its life in static variable, if it changes outside in session, you will never know. Thats why I always keep it as instance property instead of static, so I assume that atleast for this instance of page, the session value is constant.
Avoid Property of Property Style
Consider following code,
string url = HttpContext.Current.Request.Url; string method = HttpContext.Current.Request.Method;
Both method has HttpContext.Current.Request as common code, and it actually has 2 Property Evaluation codes. Considering simple property evaluation execution time is 1ms, above code finishes in 6ms.
Ideally such code should be written as,
HttpRequest request = HttpContext.Current.Request; string url = request.Url; string method = request.Method;
Now this rewritten code finishes in 4ms, as first statement executes two property evaluation code to get final useful HttpRequest object.
Caching Method Results
Sure all of above methods even apply to method results too, as Property evaluation is just an internal get_Property method.
Result
Ok fine, I do the caching but how it improves performance? The answer is quite simple, each of above discussed methods requires numerous Property evaluation, Hashtable eveluation code, in order to read certain values. Now accessing local stack variable or static variable is many times faster then accessing property as it is a new method to access some other variable or some calculated variable. The indexed or hashed properties take even more time as the search is dependent upon the number of items present in the list or dictionary. Each such operation may execute few millsecond faster then before, but the overall performance increases with many concurrent execution. Not only CPU cycles but memory usage also can be improved as less method calls, less stack in use and less overhead on memory.
Oh such big lecture just for avoiding Property Evaluations? Well yes, remember Property Evaluation code is nothing but a simple method execution for CPU. And inside the .NET CLR environment, CPU needs to do a lot before an actual code is executed. Please note, this is assumed hypothetical Call sequence, the actual .NET CLR call sequence can be much more complex.
- Access target object (in which property exists)
- Access internal "Get" method handle for this target object’s type
- Allocate the Stack
- Do some book keeping, note the pointer values for tracking Exception StackTrace
- Setup local variables if any
- Move to the pointer of first instruction
- Evaluate expressions and actual code (for NamedValueCollection this could be quite long)
- Push result on stack
- Finish the Call
- Pop the result
- Unwind stack and do some book keeping to unwind Exception StackTrace
So, you can see, CPU needs to do a lot just before it can give you property evaluation result. And in case of Cached value in local variable, this can simply reduce in one or two instructions for subsequent frequent access.
Memory Usage
Using more such cached variables doesnt increase memory overhead? Well significantly not, because you are not going to have million such variables in one single threaded execution, most of these variables will be reused from time to time. Each local cached variable in method execution is on stack, and it only takes one space unit, however executing actual property again and again will even require more stack usage.
This isn’t same as External Caching
Sure web servers are written with great deal of effort and do provide good caching mechanism. Even ASP.NET has various caching methods, but those caching things are for very generalized purpose, the methods I am detecting here is not supposed to be misunderstood with the page, control caching. Because even other caching methods requires at least first time complete processing in order to get the results. Also these are pure processor level execution improvements, it has nothing to do with where your application is executing, it can be your web server code or your mobile app code or even database assembly code.

Static Caching Config Values – .NET caches all config values automaticaly, so it wont access config file every time you request values.
Cache Before Loop – array.Length in loop is optimized automaticaly by compiler, so it does not hurt performance.
If you look carefully in Static Caching Config Values, sure .NET may cache its values under underlying hashtable, but once again, the cost of first getting instance of config holder, then getting hashtable and then searching your key in hashes and then getting results compared to accessing one static variable will not be costly?
Cache before loop – , example I gave had array.Length, but basically it implies as a general practice, because compiler can optimize only array.Length but not other properties which we could optimize. I just used it as a sample, also if you turn of optimizations in compilation, it definately hurts performance
Very good. Another option is to use static constructors to initialize, but this has an overhead on each access to the static class. So your ways here are the best in my experience.
Static constructors put too much load on application initialization and too many static constructors can also put application in deadlock state or it can hang and in such condition it can become difficult to analyze root cause of problem.
Thats why “Load on first use” is always best strategy.
While all very interesting concepts, this smells of premature optimization, which as we all know, is the root of all evil. This article would be great titled “Optimizations that are typically done in a compiler” or something along those lines. Great write up and detail.
thx for artcle, really interesting
Akash, thank you for this. Although when I run the query string caching routine I get the following error.
Using the generic type ‘System.Converter’ requires ’2′ type arguments
I copied and pasted the code from above. What am I missing?
When I mouse over Converter.ChangeType in (T)Converter.ChangeType(typeof(T), val) intellisense does not seem to find a method of Converter called ChangeType
Actually this worked… I was reading too fast to see the type-o
return (T)Convert.ChangeType(val,typeof(T));
Hi, cool post. I have been wondering about this topic,so thanks for writing.
Hi, gr8 post thanks for posting. Information is useful!
Great post! I’ll subscribe right now wth my feedreader software!
Hi, very nice post. I have been wonder’n bout this issue,so thanks for posting
How soon will you update your blog? I’m interested in reading some more information on this issue.
Very Interesting post! Thank you for such interesting resource!PS: Sorry for my bad english, I’v just started to learn this language