initial doc
[mono.git] / web / performance
1 * Writing performant .NET and Mono applications
2
3         The following document contains a few hints on how to improve
4         the performance of your Mono/.NET applications.
5
6         These are just guidelines, and you should still profile your
7         code to find the actual performance problems in your
8         application.
9
10 ** Using the Mono profiler
11
12         To obtain memory consumption and measure the time spent on
13         functions and the number of times a function is called in
14         Mono, you can invoke the runtime with the --profile flag, like this:
15
16 <pre>
17         mono --profile program.exe
18 </pre>
19
20         The above will instruct Mono to instrument your application
21         for profiling.  The default Mono profiler will record the time
22         spent on a routine, the number of times the routine called,
23         the memory consumed by each method broken down by invoker, and
24         the total amount of memory consumed, this is what it looks
25         like:
26 <pre>
27 Total time spent compiling 227 methods (sec): 0.07154
28 Slowest method to compile (sec): 0.01893: System.Console::.cctor()
29 Time(ms) Count   P/call(ms) Method name
30 ########################
31   91.681       1   91.681   .DebugOne::Main()
32   Callers (with count) that contribute at least for 1%:
33            1  100 % .DebugOne::Main(object,intptr,intptr)
34 ...
35 Total number of calls: 3741
36 ...
37 Allocation profiler
38 Total mem Method
39 ########################
40      406 KB .DebugOne::Main()
41          406 KB     1000 System.Int32[]                                  
42   Callers (with count) that contribute at least for 1%:
43            1  100 % .DebugOne::Main(object,intptr,intptr)
44 Total memory allocated: 448 KB
45 </pre>
46
47         You might want to keep a close eye on the memory consumption
48         and on the method invocation counts.   A lot of the
49         performance gains in MCS for example came from reducing its
50         memory usage, as opposed to changes in the execution path. 
51
52 ** Memory Management in the .NET/Mono world.
53
54         Since Mono and .NET offer automatic garbage collection, the
55         programmer is freed from having to track and dispose the
56         objects it consumes (except for IDispose-like classes).   This
57         is a great productivity gain, but if you create thousands of
58         objects, that will make the garbage collector do more work,
59         and it might slow down your application.
60
61 ** foreach
62
63         The <tt>foreach</tt> C# statement handles various kinds of
64         different constructs (about seven different code patterns are
65         generated).   Typically foreach generates more efficient code
66         than loops constructed manually, and also ensures that objects
67         which implement IDispose are properly released.
68
69         But foreach sometimes might generate code that under stress
70         performs badly.  Foreach performs badly when its used in tight
71         loops, and its use leads to the creation of many enumerators.
72         Although technically obtaining an enumerator for some objects
73         like ArrayList is more efficient than using the ArrayList
74         indexer, the pressure introduced due to the extra memory
75         requirements and the demands on the garbage collector make it
76         more inneficient.
77
78         There is no straight-forward rule on when to use foreach, and
79         when to use a manual loop.  The best thing to do is to always
80         use foreach, and only when profile shows a problem, replace
81         foreach with for loops.
82
83 *** Using structs instead of classes for small objects
84
85         For small objects, you might want to consider using value
86         types (structs) instead of object (classes).
87
88 ** Assisting the Garbage Collector
89
90         Although the Garbage Collector will do the right thing in
91         terms of releasing and finalizing objects on time, you can
92         assist the garbage collector by clearing the fields that
93         points to objects.  This means that some objects might be
94         elegible for collection earlier than they would, this can help
95         reduce the memory consumption and reduce the work that the GC
96         has to do.