.netCoders Contact Us
Search:

Optimization

Optimization techniques vary with the functionality in your application, so here are some general tips to optimizing performance.

Precompile with the Native Image Generator

One of the tools with the .NET Framework SDK is the Native Image Generator (ngen.exe). This tool precompiles your application and can improve that startup times over JIT compiling. The .NET Documentation describes this tool as:

"The Native Image Generator creates a native image from a managed assembly and installs it into the native image cache on the local computer. Running Ngen.exe on an assembly allows the assembly to load and execute faster, because it restores code and data structures from the native image cache rather than generating them dynamically."

For example, the following line, typed at the command prompt, generates a native image for myApplication.exe

ngen c:\myApplication.exe

Dispose of Resources

When you have a component that uses resources that need to be released, consider implementing the IDisposable interface. This is the recommended way to release resources, rather than relying on the garbage collector and the Finalize method. The IDisposable interface has one method, Dispose(), that you can implement to handle any necessary cleanup. Clients should call this method prior to de-referencing your class, or letting it go out of scope. You can also call this method from your component's Finalize method to properly free resources for the cases where the the client does not call Dispose(), and the garbage collector cleans up your object.

Resources that need to be freed include database connections and files. Here is a list of some of the classes that implement the IDisposable interface.

  • BinaryReader & BinaryWriter
  • TextReader & TextWriter
  • Component
  • SqlConnection & OleDbConnection
  • SqlCommand & OleDbCommand
  • OleDbDataReader & SqlDataReader

Use Database Connection Pooling

In order to use the database connection pooling features of ADO.NET, the connection string must be the same. If you use windows authentication, for authenticating users in the database, then connection pooling will not be used. To change this, modify your application so that it uses a single username and password to connect to the database for all users, and implement security at the application level.

Use the SqlClient Namespace

When accessing SQL Server databases, the SqlClient namespace offers significantly better performance than the OleDb namespace, since the classes in the SqlClient namespace communicate using SQL Server's native tabular data format. When the database is SQL Server and performance is paramount, use the System.Data.SqlClient namespace.

Use SqlReader for Forward-Only Data

If you need data from a database and only need to loop through it, perhaps to populate a select box, use a DataReader over a DataSet. The DataReader, such as the SqlDataReader, does not store the data in memory like the dataset, and offers much better performance in forward-only scenarios.

Cache Stored Procedure Parameters

When using stored procedures multiple times, reuse or cache the Parameters to reduce the overhead of preparing new parameter objects for every call. Although not covered on the exam, you should take a look at Microsoft's Data Access Application Block for .NET, that was built using some best practices of data access encapsulation, and features a parameter cache to improve performance.

Prepare Commands

The Prepare method, of the SqlCommand and OleDbCommand objects, creates a compiled version of the command. This can improve performance if the command is going to be re-used one or more times. For instance, the following code sample from the .NET Documentation, shows a command being prepared, and later used again. When the command is re-used, the compiled version is executed.
//Set Command object Properties
command.CommandText = "insert into Region (RegionID, RegionDescription) values (@id, @desc)" ;
command.Parameters.Add ( "@id", id) ;
command.Parameters.Add ( "@desc", desc) ;

//Prepare a compiled version
command.Prepare() ;

//Execute
command.ExecuteNonQuery();

// Change param values and call execute. This time the prepared command will be executed.
command.Parameters[0].Value = 21;
command.Parameters[1].Value = "mySecondRegion";
command.ExecuteNonQuery();

Consider Asynchronous calls and Remoting

If you have a component that takes a while to complete, consider calling it asynchronously so the calling application can continue working, or using Remoting to offload the load of that component to a dedicated server.

Compile in Release Mode

During development, you'll compile in Debug mode to get additional information about errors, and to enable debugging. However, for your production environment, be sure to compile and publish your code in the Release configuration. This removes the overhead of the debug code.