The problem of .NET execution efficiency is a common topic for a long time, which is mainly discussed around the garbage collector (GC), managed code, JIT (Just In-Time).
First, GC, in fact, the GC used in .NET is a modern, high-efficiency GC, with the LISP GC has been greatly different, and he uses a fairly complex algorithm. Using GC can make the programmer more easily, put more energy on the application's main logic, without the allocation and release of memory, of course, the GC's impact is not overlooked. When GC is running, other work will stop, but fortunately he will not run frequently.
Cute JIT, he is compiled IL into a native code when the app is executed, which is certain to consume the CPU time, but the advantage of him is much more than his shortcomings. JIT is not compiling all the code as a native code, but which method (process) is called, JIT will compile that method as the local code. JIT is also optimized for different platforms, which is not possible to achieve traditional compilers. In theory, different JIT can implement the .NET program cross-platform operation. For example: Mono (a project that implements the .NET framework on Linux, see http://www.go-mono.com/, the latest version is 0.3).
However, cross-platform is not as good as imagined, from Java's "once compiled," is running "is" once compiled, and "debugging everywhere" can be seen. This is due to the huge differences in the operating system. Therefore, cross-platform applications must be targeted to optimize different platforms, and can effectively improve the stability and efficiency of the program.
No matter what, Microsoft has made JIT. At least the current CLR 1.1 is much faster than JVM 1.4. Perhaps the 1.5 version of JVM named Tiger will greatly improve efficiency. However, performance-compiled performance is not very high in enterprise applications, so don't be too much attention to him.
In addition, there are some techniques that improve performance:
First, String and StringBuilder
When a string needs to change frequently, you should consider using StringBuilder. Although StringBuilder provides less capabilities. A compromise is that the StringBuilder is converted to String by the StringBuilder's toString (Note: .NET 1.1, no matter how explicitly or implicit conversions can be converted to String. Just call StringBuilder's Tostring () Method implementation.).
String is actually a non-changing data type, and his memory allocated in the hosted heap is just satisfying the length of the string. Modifying a string is actually created a new string, and the old string is copied to a new string when necessary. Obviously, when the string content is constantly adding, the program becomes efficient, and the old string turns garbage to increase the number of GC runs. The StringBuilder usually allocates more memory ratios. This length can be explicitly specified in a constructor overload of StringBuilder. The required memory is reassigned only when the string length is expanded. The new length is not explicitly specified, approximately 2 times the old length (Note: This Microsoft does not provide a clear document description, 2 times by observing memory change.).).
It can be seen that the use of StringBuilder can significantly reduce the number of memory repellency, copying, and the number of garbage. But this is only suitable for additional sub-strings and replace characters, delete, and insertion sub-strings remain inefficient. It is also necessary to pay attention to the use of StringBuilder needs to reference the System.Text namespace.
For arrays Array and ArrayList are similar to String and StringBuilder.
Second, DataReader's indexer
DataReader has two indexers, one is an int type, one is a String type. Both indexers use different algorithms. Simple iterative testing, using int indexer is more than 5 times more than String's indexer. This is certainly inaccurate, but at least the int indexer is more efficient. So, it is recommended to use an int inderator. However, programs with String indexers have higher readability. There is a good way to use constants to define the index of the INT indexer. E.g:
Private const INT field_table1_id = 0; // .... response.write (DataReader [Field_Table1_id] .tostring ());
Also note that when you change the SELECT query, don't forget to check if the constant is still correct.
Third, DataReader and DataSet
DataReader is a read-only forward stream that DataSet is a data set with complex structure. Populate DataReader is much faster than filling DataSet. (DataSet is filled with DataReader but DataSet is disconnected, while DataReader will turn database connections all the open state. Database connections are expensive resources, so try to use DataSet or derived strong type DataSet in DataSet. Also, when passing the data set (for example, between the layers, the WebService is sent, accept the data set) must not use DataReader.
Use DataReader in the following conditions
Quick access to the data set of the data set with a quick access to the simple control data binding
When it is an iterative DataReader, try to avoid excessive logic during iteration.
Fourth, the use of high cost resources
As mentioned earlier, database connections are a high cost resource. Establish as soon as possible and close as possible as possible. Using the Try ... catch ... FinalLink in C # ensures that the database connection is turned off in Finally, but sometimes you may forget the code to write Connection.Close (). Another method is to use the use of the statement, for example:
Using (SqlConnection Connection = New SqlConnection) {connection.open (); // ...}
After the field is dominated, the CLR will automatically call the Dispose () method. (Objects in the USING statement must implement IDisposable interface) This method ensures that a Close () method is executed, but it is not conducive to exception handling. Comprehensive way, you can neat using in TRY, for example:
Try {Using (SqlConnection Connection = New SqlConnection) {connection.open (); // ...}} catch (exception ex) {// ...} finally {// ...}
In addition, when processing the DataAccess layer in the multi-layer application, the class should be implemented for the idisposable interface. Five, pointer
An older talk, please remember: You are programming in the hosted environment provided by .NET, so if you don't have a very necessary and adequate reasons, please do not use the pointer. In C , the pointer is very flexible, but it is also very dangerous. In .NET, some features of the pointer can find alternatives, such as function pointers can be replaced by delegate. One advantage of the use of entrusted is that the type of principal is very high. However, some tasks must not be avoided to use pointers, such as writing debuggers.
When you use a pointer, the CLR thinks you know what you are doing. Because the pointer will bypass security check at all runtime.
Another point, a program containing an unsafe code (one of the pointers is one) may be prohibited from running (the final decision is in the user's hand).
Sixth, other supplements
In .NET, you can use an abnormal mechanism as you want, of course, pay attention to the processing level. He will not have a big impact on performance. This is different from C , so C programmers can use it with confidence.
Pay attention to later binding, try to avoid using this technique.
Reference Bibliographic and Website:
"C # Advanced Programming" Tsinghua University Press
"ASP.NET Advanced Programming" Tsinghua University Press
".NET Framework Advanced Programming" Tsinghua University Press
"ADO.NET Advanced Programming" China Power Press
".NET programming core programming" Tsinghua University Press
MSDN (http://www.microsoft.com/msdn)
9cbs (http://www.9cbs.net)
Developer Club (http://www.dev-club.com)