Performance fine tuning with SharePoint Object Model

Scenario 1 : Retrieve SPList instance

SPWeb.Lists (“name”) – Not Good
          using (SPSite site = new SPSite(strSite))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    SPList oList = web.Lists ["MyList"]
                }
             }
In this case, it loads the metadata* of the all lists in that specific SPWeb object. Then it does SPList.Title comparison with metadata of all the lists returned and then it returns the matching list from the SPWeb.Lists collection.



SPWeb.GetList (string strUrl) – Good
using (SPSite site = new SPSite(strSite))
      {
       using (SPWeb web = site.OpenWeb())
        {
          SPList oList = web.GetList("/Lists/MyList/AllItem.aspx")
        }
      }
In this case, first retrieves the list GUID from the url (database hit), then it loads the metadata* for that specific list.

metadata * = list of all information of List like its schema, fields info, content type info, column and items count.
Consider a scenario of a SharePoint site which contains 1000 lists.
If we use SPWeb.GetList(), it will load the SPList by finding out the exact GUID of that SPList from the SharePoint content DB and loads the metadata.
But if that is the scenario with SPWeb.Lists[“MyList”] then, SPWeb.Lists will load the metadata of  all the 1000 lists in memory and then it does SPList.Title  ( here it is “MyList”) comparison with metadata of all the lists returned and then it returns the matching list from the SPWeb.Lists collection.

Scenario 2 : Retrieve SPListItem

SPList.Items[int idx] – Not Good
          using (SPSite site = new SPSite(strSite))
            {
                using (SPWeb web = site.OpenWeb())
                {
                  SPList oList = web.GetList("/Lists/MyList/AllItem.aspx");
                    for(int idx =0; idx< oList.ItemCount; idx ++)
                    {
                        string strLstItemName = oList.Items[idx].Name;
                    }
                }
            }
In this case, for each iteration oList.Item[idx] will load a SPListItemCollection. Eg: consider a list has 1000 list items. So whenever this code executes, for each iteration it will create a separate SPListItemCollection and it will create a huge memory consumption in the GC Heap by creating 1000 SPListItemCollection instances



SPListItemCollection[int idx] -  Good
  using (SPSite site = new SPSite(strSite))
            {
                using (SPWeb web = site.OpenWeb())
                {
                   SPList oList = web.GetList("/Lists/MyList/AllItem.aspx");
                    SPListItemCollection oListItems = oList.Items;
                    for(int idx =0; idx< oList.ItemCount; idx ++)
                    {
                        string strLstItemName = oListItems[idx].Name;
                    }
                }
            }              
In this case, we can see the the only code change between this one and the not good one is, here we are first taking all the items from the list and populating it in a SPListItemCollection. And then we are iterating only that SPListeItemCollection and finding out the specific list item. Here the advantage is that, in the memory this code will load only one SPListItemCollection.

Scenario 3 : Retrieve SPListItem Count

SPList.Item.Count – Not Good
using (SPSite site = new SPSite(strSite))
      {
       using (SPWeb web = site.OpenWeb())
        {
          SPList oList = web.GetList("/Lists/MyList/AllItem.aspx");
          int iCount = oList.Items.Count;
        }
      }
In this case, oList.Items.Count, first it will load all the SPListItems in the memory and then it will find out the total count. For eg: Consider a list with 1000 list items. Then in this scenario the above code will load all the 1000 SPListItems and then return the total count, which will really create some performance hit.



SPList.Item.ItemCount – Good
using (SPSite site = new SPSite(strSite))
      {
       using (SPWeb web = site.OpenWeb())
        {
          SPList oList = web.GetList("/Lists/MyList/AllItem.aspx");
          int iCount = oList.ItemsCount;
        }
      }
In this case, ItemCount is a part of metadata of the SPList object and this will get generated whenver we create a SPList instance. So there is no any overburden to the list to find out its total number of list items.


Scenario 4 : A list of recommended  properties and methods

Not Good (replace this by the Good one)
Good 

SPList.Items.Count

SPList.ItemsCount

SPList.Items[Guid]

SPList.GetItemByUniqueId(Guid)

SPList.Items[Int32]

SPList.GetItemById(Int32)

SPList.Items.GetItemById(Int32)

SPList.GetItemById(Int32)


Comments

Popular posts from this blog

Switch from Classic to Claims Authentication in SharePoint 2010

How to query list data using web service