* Prefer String.Compare to changing case If you need to compare strings ignoring case, you should use String.Compare rather than calling ToLower on both. This avoids allocations. * Prefer ToLower to ToUpper Apparently, ToLower is faster. * Use the InvariantCulture InvariantCulture should be used for all "non-linguistic identifiers" (see http://tinyurl.com/9vqus -- the 2.0 string recommendations). It is faster and more correct. Some methods in the string class that you might not think are culture sensitive really are. The following methods are culture sensitive: - .CompareTo - .ToUpper - .ToLower - .StartsWith - .EndsWith - .IndexOf (string, ...) - .LastIndexOf (string, ...) The methods in System.Web.Util.StrUtils exist to make correct calls less verbose. They use the InvariantCulture. * Size of controls In controls, it is important to keep the size of controls small. Controls can be replicated many times on a page due to data bound controls. The more memory each control allocates, the more GCs we have to go through. * Avoid extra fields There are a few techniques to save space in the number of fields. * Use [Flags] enums rather than many bool's Each bool takes up 1 byte. If you use a flags enum you can pack 8 bools into the same amount of space. * Use the Events framework Every time you say public event EventHandler x; it creates a field. Most of these fields never get used. Control has a property called Events which holds a linked list of events that get created. Thus, events only take up space when one uses them. An example of using this: static object event_name_blah = new object (); .... public event EventType EventName { add { Events.AddHandler (event_name_blah, value); } remove { Events.RemoveHandler (event_name_blah, value); } } .... If your control has a OnEventName that invokes EventName, you have to do: EventType deleg = (EventType) Events [event_name_blah]; if (deleg != null) delege (arguments); * ViewState Keep the view state small. Remember that whatever gets stored in ViewState after tracking starts needs to be sent over the wire. Store in ViewState the minimum amount of objects needed to restore your state. * Store optimized classes. It is important to store things in terms of primitive types (int, short, bool, byte, string), Hashtables, ArrayLists, object arrays, and specially optimized types (Unit, Color, Pair, Triplet) when saving viewstate. Otherwise, things will have to be put in a more expensive format over the wire. * Store int values rather than enums. If you store an enum, the fully qualified name to the enum needs to be sent over the wire. Cast the enum value to an integer when storing it in view state. Keep in mind that object o = 1; MyEnum e = (MyEnum) o; Works, so you don't need any complex code when getting the stuff back. * Return null in SaveViewState when possible For example, if you normally save the state of your 3 children to a triplet, but all 3 values are null, return null, rather than new Triplet (null, null, null); Often, doing this allows the framework to avoid saving anything about many layers of controls in the viewstate. * Cache in variables Accessing a property in the controls usually means reading from ViewState. Try assigning property values to local variables if they are going to be used more than once and are known to not change while a given method runs. * Handle Enabled and Visible. If Enabled is false, your control should not handle any postback. If Visible is false, your control does not render anything (but still keeps its state). Usually the parent takes care of that.