1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
* 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.
|