It’s been some time since my last post. But since then I’ve seen recurring “errors in thinking” in SharePoint development, which convinced me to start a series on writing code that’s not just correct — but faster and better.
I never criticize other developers’ code. You never know the context — time pressure, knowledge gaps, or habits from years ago. But as a consultant, it’s worth asking yourself: can this be done faster? is this the right way?
Tools Worth Mentioning
Before diving in: SPCop (free) and SPCaf are worth installing. They encapsulate SPDisposeCheck and much more. I’d even suggest integrating them with TFS so developers get a full report on every check-in.
SPLimitedWebPartManager Disposal
One that SPDisposeCheck still misses: the rootweb of SPLimitedWebPartManager is not being disposed in many codebases.
SPLimitedWebPartManager manager = SPContext.Current.Web.GetLimitedWebPartManager(
Page.Request.RawUrl, PersonalizationScope.Shared);
manager.Web.Dispose(); // ← this needs to be called manually
Forgetting manager.Web.Dispose() causes memory leaks. It keeps showing up.
Items.Add() vs AddItem()
Two ways to add an item to a list:
// SharePoint 2007 way — iterates the entire collection
SPList.Items.Add();
// SharePoint 2010+ way — executes a targeted query
SPList.AddItem();
Both add an item. But Items.Add() iterates over all existing items to find the last ID before returning the new item object. If your list has thousands of items and you’re doing this frequently, you’re hammering the backend unnecessarily. Use AddItem().
Items.Count vs ItemCount
Same principle:
// BAD: fetches and iterates the entire collection
int count = SPList.Items.Count;
// GOOD: reads a cached property, no collection iteration
int count = SPList.ItemCount;
And never do this:
// HORRIBLE — iterates the entire collection on every loop iteration
for (int i = 0; i < 100 && i < activeList.Items.Count; i++)
{
SPListItem listItem = activeList.Items[i];
// do something
}
Use ItemCount instead:
for (int i = 0; i < 100 && i < activeList.ItemCount; i++)
{
SPListItem listItem = activeList.Items[i];
// do something
}
ItemCount is just a property that gets updated on every item add — it’s instant. Items.Count re-fetches everything.
String Concatenation Performance
This one surprised me. Three ways to concatenate strings:
// 1. Simple +
string result = "test" + "test2" + "test3";
// 2. String.Format
string result = string.Format("{0}{1}{2}", "test", "test2", "test3");
// 3. StringBuilder
string result = new StringBuilder().Append("test").Append("test2").Append("test3").ToString();
Fastest to slowest: 1, then 3, then 2.
string.Format at the back was a surprise to me. Of course the impact depends on how frequently you call it and how large the strings are — but if you’re doing this in a tight loop, it matters.
SPSecurity.RunWithElevatedPrivileges
Not a performance issue, but a best practice worth discussing.
Most SharePoint developers know RunWithElevatedPrivileges but few ask themselves if it’s actually the right tool. Running code inside that delegate makes it all-powerful — it can also touch the file system of the server. That’s more power than you usually need.
// Common pattern — more powerful than necessary
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(SPContext.Current.Site.ID))
using (SPWeb web = site.OpenWeb())
{
// ...
}
});
Alternative: use the SystemAccount.UserToken overload:
using (SPSite site = new SPSite(SPContext.Current.Site.ID,
SPContext.Current.Site.SystemAccount.UserToken))
using (SPWeb web = site.OpenWeb())
{
// ...
}
This keeps you within SharePoint boundaries and doesn’t grant file system access. Still elevated, but more scoped.
Edit (6/10/2014): After reviewing this together with Karine Bosch, she pointed out that the
SystemAccount.UserTokenapproach takes longer to run thanRunWithElevatedPrivileges. If anyone knows a third option that’s both scoped and fast, let me know in the comments.
Think about it and let me know if you have comments. This is fine for a handful of users — but when your solution serves 50,000 people, every one of these patterns has a measurable impact.