Valid tive C # Item 16: Minimize garbage
When we use C #, GC (Garbage Collector) will help us to manage memory resources very efficiently, and it will clean up meaningless objects very efficiently. However, even if you work more efficiently, frequent allocation and destruction of objects in the heap will also reduce the efficiency. If we create a large number of reference types in the program, it will affect the execution efficiency to a certain extent.
Therefore, we should not make GC overwork. We can use some simple methods to minimize GC operations in our program. All reference types are allocated memory on the stack. When a function call ends, local variables in the function become garbage. In the following example, the opposite is typical:
Protected override void onpaint (painteventargs E)
{
Using (font myfont = new font ("Arial", 10.0f ))
{
E. Graphics. drawstring (datetime. Now. tostring (), myfont, brushes. Black, new pointf (0, 0 ));
}
Base. onpaint (E );
}
The onpaint () method is called frequently. A font object is created each time it is called, and the content of this object is the same. GC needs to clear these resources after each call, which reduces the efficiency.
We can change the font object from a local variable to a member variable, so that we don't have to re-create it every time.
Font myfont = new font ("Arial", 10.0f );
Protected override void onpaint (painteventargs E)
{
E. Graphics. drawstring (datetime. Now. tostring (), myfont, brushes. Black, new pointf (0, 0 ));
Base. onpaint (E );
}
Now our program will not produce unnecessary garbage when calling the paint, and the GC work will be reduced accordingly, thus improving the efficiency. When we convert local variables to member variables to reduce garbage, we should implement the idisposable interface of this object type. So that we can release its resources at the end.
When our local variables are of reference type and frequently called, we should promote them to member variables. Font is a good example. However, this can only be done when it is frequently called. Our goal is to reduce garbage, rather than turning all local variables into member variables.
Another way to avoid repeated object creation is to use static members. One example is burshes. Black. Every time we draw a window, we need to use it. If we create a new brush every time, we need to destroy a lot of repeated brushes. Therefore, the designer of. NET Framework creates a brushes class, which contains a lot of static objects of the brush.
Private Static brush _ blackbrush;
Public static brush black
{
Get
{
If (_ blackbrush = NULL)
{
_ Blackbrush = new solidbrush (color. Black );
}
Return _ blackbrush;
}
}
The brushes class creates a black brush for the first time. This black brush will be used all the time. In addition, the paint that we do not need, such as green, will never be created. In this way, we can get the desired result at the minimum price.
Two methods to reduce spam are mentioned above. One is to promote local variables to member variables, and the other is to declare static members of the class. Another way is to provide the final value for the immutable type, instead of modifying it frequently. System. String is an unchangeable type. After we construct a string, its content will not be modified. When we modify the string, we actually create another string object, and the original object becomes garbage:
String MSG = "hello ,";
MSG + = thisuser. Name;
MSG + = ". Today is ";
MSG + = system. datetime. Now. tostring ();
The above example is equivalent to the following code:
String MSG = "hello ,";
// This statement is invalid, for example only
String temp1 = new string (MSG + thisuser. Name );
MSG = temp1;
String temp2 = new string (MSG + ". Today is ";);
MSG = temp2;
String temp3 = new string (MSG + system. datetime. Now. tostring ());
MSG = temp3;
Tmp1, tmp2, tmp3 and the created MSG are all junk. + = The operation creates a new string in the string class to modify it, instead of modifying an existing object. We can use the format () method to create a string:
String MSG = string. Format ("Hello, {0}. Today is {1}", thisuser. Name, datetime. Now. tostring ());
For the creation of more complex strings, we can use the stringbuilder class:
Stringbuilder MSG = new stringbuilder ("hello ,");
MSG. append (thisuser. Name );
MSG. append (". Today is ");
MSG. append (datetime. Now. tostring ());
String finalmsg = msg. tostring ();
Stringbuilder is a variable type that can create an unchangeable string type. It provides variable strings for easy modification for us to create and modify. More importantly, it can provide us with some class design ideas. When creating an unchangeable type, we should also consider creating a constructor for it to complete the work of frequent modification and return the target object.
GC is very efficient, but it still takes time to create and destroy objects on the stack. We should avoid creating useless objects and creating a large number of repeated objects. Finally, you should pay attention to the creation and modification of unchangeable types.
Translated from Objective C #: 50 specific ways to improve your C # by Bill Wagner
Back to directory