Saturday, February 1, 2014

Performance improvement tips in ASP.NET:

Performance improvement tips in ASP.NET:

After a long gathering , analyzing & optimizing about Performance Improvement needs, I have finalized & writing the most required tips which every smart developer or programmer must know, Of course it took much time for optimization & representation, but you can enjoy it in little timespan.
While explaining to the tips I have even cleared many other concepts too, so take time to understand each tip with detail look.

I would expect your precious suggestions & comments in the comment box.

1)    Avoid Server side validations to the most you can, try to manage at client side since server side validations consume valuable resources on your server.
(Mostly new programmers do this mistake need to be avoided)

2)    Avoid viewstate maintenance & images use except whenever you required I would turn off viewstate at page level and will invoke for the control for which I really need.
At page level <%@ Page EnableViewState="false" %> & at for the control
<asp:TextBox ID="txtNeedtoBesavedUponPostBack" runat="server" EnableViewState="true"></asp:TextBox>
As you know view state maintains the data across post backs on the webpage itself in Base64Encoded format, which increases the page size & due to which your page performance affects.
Same thing happens with images use as minimum images in the page you can,But if in case you really required then use small in size images or do image compression with 3rd party tools and then use.

3)    Make sure to execute the code if & only if you required I know many developers won’t    bother to check properly with Page.IsPostBack property. If you use it properly then it will avoid your code to execute unnecessarily which would boost your code performance
, in the same way make sure in other places too with if conditions to avoid unreasonable executions.

4)    Throw fewer exceptions, it will slow down your performance try to write a code such that it won’t happens & use it only in an exceptional & mostly required cases.
I wanted to share one point here i.e. the difference in throw ex & throw:   
The basic difference is that the ‘throw exception’ overwrites the stack trace i.e. resets the stack trace and this makes it hard to find the original code line number that has thrown the exception, ‘throw’ basically retains the stack information and adds to the stack information in the exception that it is thrown.
·         An added benefit of not re-setting the stack trace is that the code will run faster, as the unnecessary stack capture is avoided.

5)    Do Proper String Manipulations:

·         When you combine more than 4 strings use stringBuilder.Append() rather than using ‘+’ or string.Concatinate(). Because strings are immutable, the concatenation operator (+) actually creates a new string out of the two originals and then points the original string instance at the new string where as stringBuilder points to one memory and whenever something is added it will get copied into that memory area.

·         If your are using stringBuilder to just add 2to3strings then it’s nonsense,StringBuilder can be used where more than 3 to 4 or more strings concatenations takes place & when  you try to do some other manipulation (like removing a part from the string, replacing a part in the string, etc.).
And when you compare strings never compare as string1.ToUpper() == string2.ToUpper() ,It will create temporary strings and then compare ,use string.Compare() which will improve your performance.

6)    Check the Connection Pool
Connection object is one of most resource consuming object in ADO.NET. So we need to manage this object very carefully, setting a Pooling =True would improve your performance to great extent.
Ex:
     con.ConnectionString = "Data Source=.\\SQL_INSTANCE2;Initial Catalog=dbPOSPRO;  Integrated Security=True;Pooling=True" ;

By Default we’ll have 100 pools. When the first user enters into our website and tries to open one connection, then the first connection pool is created. Now 99 pools are remaining. At the same time, one more user tries to open a connection with the same string then our pooler checks whether any opened pools with same connection string are becomes free and available?. If the first user closes the connection, that pool will be free and 2nd user starts using the same pool. So this second user also uses the same pool and we can get more performance and resources. Suppose if the pool is not freed and the first user is still using it, what the pooler will do from the remaining 99 pools is that it will create one more pool and use it.        
For large website you can increase the no.Of Connection pools by setting Max pool size Property in Connection string.ex: Max pool size =’1000’
Ex:             
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Data.SqlClient;
namespace Test1
{
    class TestConnection
    {
        public static void ConnectionWithPool()
        {
            SqlConnection con = new SqlConnection ();
            con.ConnectionString = "Data Source=.;Initial Catalog=test;Integrated Security=True;Pooling=True";
            for ( int i = 0; i < 100; i++)
            {
                con.Open();
                con.Close();
            }
        }
        public static void ConnectWithoutPool()
        {
            SqlConnection con = new SqlConnection ();
            con.ConnectionString = "Data Source=.;Initial Catalog=dbPOSPRO;Integrated Security=True;Pooling=False" ;
            for ( int i = 0; i < 100; i++)
            {
                con.Open();
                con.Close();
            }
        }
    }
    class Program
    {
        static void Main( string [] args)
        {
            Stopwatch sw = new Stopwatch ();
            sw.Start();
            TestConnection .ConnectionWithPool();
            sw.Stop();
            Console .WriteLine( "Time Taken With Pooling: " +sw.ElapsedTicks);
            sw.Restart();
            TestConnection .ConnectWithoutPool();
            sw.Stop();
            Console .WriteLine( "Time Taken Without Pooling: " + sw.ElapsedTicks);
            Console .ReadLine();
        }
    }
}

O/p: Time Taken With Pooling: 169725
     Time Taken Without Pooling: 625075

I hope you understood the difference

7)    Use Proper Cache to improve your performance.

Friends believe me I have been in to Cache Performance checking & found proper cache using will enhance your code performance to great extent.
As you know Cache used to store commonly used items in the memory and returns whenever requested it does not create the items from scratch.
As a .Net Programmer you aware of Page life Cycle, when webpage (let us say its content won’t change up to one hour) is requested, then it has to come from all the Page life cycle events initialization, Load, Rendering etc.
If thousand customers want the same page then ASP.NET will execute the same page for thousand times.
So, What will I do here is When 1st User Request for this page I will store it in the Cache memory for 1hr and this page will be responded to remaining users for 1hr from the cache memory(no again execution again & again so boost your performance to a lot).
So this can be done with OutputCache: (Duration is in Sec => 1hr = 60x60)
<%@ OutputCache Duration="3600" VaryByParam="none" %>

I don’t want to go into much details here, It has various other options like VaryByParam which is used to set the Query String name and Page will only be loaded before specified Duration when there will be change of Querystring.

   Cache.Insert(....); is also used to stores the Cache with different options.

     The interesting thing is here is you can even load the Cache with various cache items   dependency I’m showing you some examples below to understand.
        In PageLoad I will Call CreateMenu()
       string menuPath = @"D://data//Menu2.xml";
       private void CreateMenu()
       {
              //string folderName = "YourFolderName/";
              DataSet ds = null;
              if (Cache["Menu"] == null)
              {
                     ds = new DataSet();
                     ds.ReadXml(menuPath);
                     RegCache(ds);
              }
       }

       public void RegCache(DataSet ds)
       {      // menu is created
              Cache.Insert("Menu", ds, new System.Web.Caching.CacheDependency(
              menuPath),System.Web.Caching.Cache.NoAbsoluteExpiration,
              TimeSpan.FromSeconds(60),
              System.Web.Caching.CacheItemPriority.Default,
              new System.Web.Caching.CacheItemRemovedCallback(
              MethodWhenCacheExpired));   
       }
      

       private void MethodWhenCacheExpired(string key, object value,CacheItemRemovedReason reason)
       {

              DataSet ds2 = new DataSet();
              ds2.ReadXml(menuPath);
              RegCache(ds2);
}
      
When Page is Loaded XML file is read into DataSet and will be registered in the Cache from RegCache().
According to the options given by me, Cache will get expired after 60Sec & MethodWhenCacheExpired() gets call, here  I am registering the Cache. The another interesting thing over here is before 60 Sec or whenever if your file gets changed then also it will call the MethodWhenCacheExpired().
In the Same way you can also Create Cache Item Dependency over SQL Database or Table i.e. you can make a call only whenever there is a change in DB or Table.
To know more look here
I would feel you now have a correct idea about cache and how it will improve performance and how to use it properly.

8)        Enabling Compression in your machine ,server or from application will allows you to reduce the response size to great extent & will help the clients (browsers) to quickly grab the response from the server. You can enable compression in ASP.NET using this link.

9)       By bundling and minifying or I can say reducing external scripts and style-sheets will help you to reduce the download size and time which will also improves application performance. Here is a great resource about Bundling and Minification Supported in 4.5,for other  previous frameworks try to minify the css,js (i.e 2 CSS into 1,2JS into 1)files as much you can and use minified versions of js files in production environment, try to bundle the DB multiple calls into 1.
It will reduce the no.Of HTTP requests to Server which will boost your performance, there are still many other ways to reduce No Of HTTP I discussed is the most required once.

10)     Turn Off Tracing & Do Publish In Release Mode while deploying in to Production Server,Deploy in Release mode would speed up your performance and Turn Off the tracing in Productin which you would not needed it will add a lot of overhead to your application you can turn it off as below in web.config:
<configuration>
<system.web>
<trace enabled="false" pageOutput="false" />
<trace enabled="false" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true"/>
<compilation debug="false" />
</system.web>
</configuration>

11)     Don’t forget to close and dispose the connections, objects at end, finally block is the best place to do that and the other best way is use using block which automatically dispose the object at the end, it will really improves the performance.
          I would recommend you to  read very nice link to understand more better about it.

12)     Other Tips:

Use a += b instead of a = a + b. Since a can be arbitrarily complex, it can result in lots of unreasonable work. It forces the JIT to evaluate both copies of a, and many of the times it’s not needed. The first statement is far better than the other since the JIT can avoid evaluating the a twice.

Use proper object initialization:Class a = new Class(); a.Val1 =”blah1”;a.Val2=”blah2”; can be done as Class a = new Class(){Val1 = “blah1”,Val2=”blah2”}; which assigns the parameters in one call improves performance.

 Avoid assigning nonsense value to variables, for 
ex: bool val; here val by default is  false for Boolean data type if
I am assigning is bool val = false then it takes my resources and affects performance.

 Coming to DB Side use SP’s rather than Query’s which are Precompiled,
 use Connection Pooling I already explained above, get the record only 
           you want and fill the Dataset with only the required details, try to make 
           minimize the  DB calls into 1 or minimum you can, 
           Turn Off the Features which you  don’t use 
ex: SqlConnection conn = new 
SqlConnection("Server=ser01;Integrated Security=true;Enlist=false");
Turn off automatic transaction enlistment if it is not needed it applies 
to others too,
Use indexes logically for the SQL DB Tables which boost the performance 
see here. Pick DataReader over DataSet whenever you can. 
I hope you have benefited,leave your comments below 





No comments: