By John Belthoff / In Web / Posted Oct 16, 2009
About 2 years ago I stumbled upon the little gem known as the Generic List. To be specific; System.Collections.Generic.List. It is my hope after your done reading this series of articles that you will come to stop using the bloated ADO.Net objects and start writing efficient code. Stick with me to find out!
This little baby has given me more trouble, performance gain and everything else imaginable and because of this I thought I would sing its praises this to you this afternoon in a series of articles.
Let's take this puppy for a ride! Create a test page and add the following to the using block; using System.Collections.Generic; and then let's stuff our list with some data.
using System; using System.Data; using System.Configuration; using System.Collections; using System.Collections.Generic; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class list_t : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { List<string> l = new List<string>(); for (int i = 0; i < 100000; i++) { l.Add(i.ToString()); } Response.Write(l.Count.ToString()); } }
As you can see we have a list of 100 thousand strings. Simple enough right? Ok let's try to find a value in that list and measure some performance. First we will turn on our Asp.Net trace in the .aspx page and run some basic code to look for values in our list.
List<string> l = new List<string>(); for (int i = 0; i < 100000; i++) { l.Add(i.ToString()); } Trace.Warn("Contains", "Starting"); if (l.Contains("49999")) Response.Write("Yes"); else Response.Write("No"); Trace.Warn("Contains", "Ended"); Trace.Warn("Contains", "Starting"); if (l.Contains("95842584147")) Response.Write("Yes"); else Response.Write("No"); Trace.Warn("Contains", "Ended");
On my machine I am finding, or not finding, that value in between 0.001270 and 0.002004 which is not bad. What's a couple of milliseconds between friends? But let's see if we can speed things up a bit and to do that we need to sort our list and try again using the binary search method of our List
l.Sort(); Trace.Warn("BinarySearch", "Starting"); if(l.BinarySearch("99799") > -1 ) Response.Write("Yes"); else Response.Write("No"); Trace.Warn("BinarySearch", "Ended");
Ah now by sorting our list and using the binary search I have just scanned a 100 thousand row record set in about 60 uSecs: 0.000068 in the application side. Not bad for an old guy huh?
Now I know what you're asking... What does this all mean? Well, say goodbye to all of those bloated ADO.net methods! Stick with me in my next addition and I will explain why I have come to that conclusion.
For now... Happy coding!
Aspx:
<%@ Page Language="C#" AutoEventWireup="true" trace="true" CodeFile="list-t.aspx.cs" Inherits="list_t" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <div> </div> </form> </body> </html>
C#:
using System; using System.Data; using System.Configuration; using System.Collections; using System.Collections.Generic; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class list_t : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { // Create our List List<string> l = new List<string>(); // Stuff it with Data for (int i = 0; i < 100000; i++) { l.Add(i.ToString()); } Response.Write(l.Count.ToString()); // Measure Performance With Trace.Warn("Contains", "Starting"); if (l.Contains("49999")) Response.Write("Yes"); else Response.Write("No"); Trace.Warn("Contains", "Ended"); // Measure Performance Without Trace.Warn("Contains", "Starting"); if (l.Contains("95842584147")) Response.Write("Yes"); else Response.Write("No"); Trace.Warn("Contains", "Ended"); // Sort our List l.Sort(); // Measure Performance After Sorting our list Trace.Warn("BinarySearch", "Starting"); if(l.BinarySearch("99799") > -1 ) Response.Write("Yes"); else Response.Write("No"); Trace.Warn("BinarySearch", "Ended"); } }