Showing posts with label Optimize C#. Show all posts
Showing posts with label Optimize C#. Show all posts

Wednesday, 1 February 2012

C# StringBuilder Optimization Tip

In this tip, you want to see how you can optimize the StringBuilder type's Append method in certain cases that deal with short strings. Instead of appending a string literal that contains two characters, you can append two characters separately. Here, we describe why this optimization works and when to apply it.

Test program

This program benchmark harness demonstrates how you can express a two-character append operation in two different ways. In the first tight loop, two space characters are appended in separate method calls; in the second tight loop, a two-character string is appended in a single method call. The first loop has better performance despite being longer to type into code.
Program that tests StringBuilder optimization tip [C#]

using System;
using System.Diagnostics;
using System.Text;

class Program
{
    const int _max = 10000000;
    static void Main()
    {
 StringBuilder builder = new StringBuilder();
 var s1 = Stopwatch.StartNew();
 for (int i = 0; i < _max; i++)
 {
     // Append two characters.
     builder.Append(' ');
     builder.Append(' ');
 }
 s1.Stop();
 builder = new StringBuilder();
 var s2 = Stopwatch.StartNew();
 for (int i = 0; i < _max; i++)
 {
     // Append two characters combined into a string.
     builder.Append("  ");
 }
 s2.Stop();
 Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000 * 1000) /
     _max).ToString("0.00 ns"));
 Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000 * 1000) /
     _max).ToString("0.00 ns"));
 Console.Read();
    }
}

Output

12.99 ns
15.29 ns

Why does this work? The reason appending two characters separately to a StringBuilder is faster is because the string type in the C# language has some complexities that characters do not have. A char type can be represented by a small integer, while a string type must be allocated on the managed heap and have its own memory location.
The string type is a full-fledged object while a char is a number only. To resolve the string argument in Append, the StringBuilder must reference all the characters separately. However, the control path for the char overload is more direct and therefore faster.

When to use char appends? At some point, using separate character appends will slow down the method you are writing. My testing showed that using chars for 1, 2, 3 and often 4 character long strings was more efficient. Longer than that and the strings were more efficient. This may involve locality of reference or simply better string copying routines, such as those that unroll loops and use unsafe code.
What about Response.Write? The Response.Write method, which is often used in ASP.NET, can use this same optimization and the results are sometimes more pronounced. I tested Response.Write and found that single-character writes were faster in sequences of two than two-character string writes.

Summary

In this tip, we looked at one way you can perform micro-optimizations on the StringBuilder type in the C# programming language. While this is not a dramatic performance boost in many cases where StringBuilder is used, it can provide a measurable speedup to much StringBuilder code as well as Response.Write code.

C# Replace Optimization

You have a method in your C# program that replaces many strings with other strings. This method can require a lot of time to run because it tries to replace so many things. In this article, we look at a way you can improve the performance of this kind of method without using any advanced data structures.

Examples

Let's look at the initial version of the method. It runs four Replace calls on the formal parameter to the method. String literals are used as the argument. When looking at the string literals, you can see that they contain some common substrings: two contain "<span>C" and two contain "<span>D". This property can be used to optimize.
First version of method [C#]

static string A(string text)
{
    text = text.Replace("<span>Cat ", "<span>Cats ");
    text = text.Replace("<span>Clear ", "<span>Clears ");
    text = text.Replace("<span>Dog ", "<span>Dogs ");
    text = text.Replace("<span>Draw ", "<span>Draws ");
    return text;
}

Second version of method [C#]

static string B(string text)
{
    if (text.Contains("<span>C"))
    {
 text = text.Replace("<span>Cat ", "<span>Cats ");
 text = text.Replace("<span>Clear ", "<span>Clears ");
    }
    if (text.Contains("<span>D"))
    {
 text = text.Replace("<span>Dog ", "<span>Dogs ");
 text = text.Replace("<span>Draw ", "<span>Draws ");
    }
    return text;
}
Second version. Now let's look at the optimized version. This version uses the Contains method around all the Replace calls with the specified common string literal. Thus, in version B, the first two Replace calls are only run when the common pattern is found; the second two Replace calls are also guarded.
Note: Another approach would be to use text.Contains("<span>"). This could be beneficial depending on how common that string is in the hypothetical data set.

What about StringBuilder?

The StringBuilder type contains a Replace method. This can help optimize certain situations, but the Replace call will require a search through the entire string still. If not many replacements occur, the StringBuilder will actually be slower because of the initial cost of the StringBuilder.

Summary

This replace optimization uses a heuristic to improve performance. If all the replacements always are run, guarding them in this way will hurt performance. If there are no good substrings to test for, this optimization will also not help. However, if many replacements are run, not all actually change the string, and they contain common character sequences, this technique can reduce the computational requirements of your method considerably.

C# Optimization Secrets

You want to see ways you can add performance optimizations to your C# programs, focusing on the level of the code statements and methods. While high-level considerations, and factors external to your code are often most important, such as computer processor and network speed, there are many low-level performance optimizations you can do inside the C# language that can improve performance. We describes these optimizations.
Tip: Focus on the "hot paths" in your program for optimizations.

Overview

In this overview, we describe the general considerations when optimizing your C# code. First, the C# language is compiled, and with the .NET Framework, you can attain performance close to languages such as C or C++.
Generally, using the simplest features of the language provides the best performance; for example, using the for-loop and avoiding parameters and return values is typically fastest. You must balance these performance goals with code readability and understandability.

Benchmark

At all levels of performance optimization, you should be taking measurements on the changes you make to methods. You can do this with the .NET Framework methods available in the Stopwatch type. It often pays to create a multitude of console programs where the methods are benchmarked repeatedly on data as it changes. You should always avoid regressing performance unless there is a clear reason to do so.

Static methods

In the C# language, non-inlined instance methods are always slower than non-inlined static methods. The reason for this is that to call an instance method, the instance reference must be resolved, to determine what method to call. Static methods do not use an instance reference.
If you look at the intermediate language, you will see that static methods can be invoked with fewer instructions. You can see an experiment based on the callvirt and call instructions on this site.

Avoid parameters

When you call any method in the C# language that was not inlined, the runtime will actually physically copy the variables you pass as arguments to the formal parameter slot memory in the called method. This causes stack memory operations and incurs a performance hit. It is faster to minimize arguments, and even use constants in the called methods instead of passing them arguments.

Avoid local variables

When you call a method in your C# program, the runtime allocates a separate memory region to store all the local variable slots. This memory is allocated on the stack even if you do not access the variables in the function call. Therefore, you can call methods faster if they have fewer variables in them.
One way you can do this is isolate rarely used parts of methods in separate methods. This makes the fast path in the called method more efficient, which can have a significant performance gain.

Constants

In the .NET Framework, constants are not assigned a memory region, but are instead considered values. Therefore, you can never assign a constant, but loading the constant into memory is more efficient because it can injected directly into the instruction stream. This eliminates any memory accesses outside of the memory, improving locality of reference. The performance advantage of const fields is demonstrated on this site.

Static fields

Static fields are faster than instance fields, for the same reason that static methods are faster than instance methods. When you load a static field into memory, you do not need the runtime to resolve the instance expression. Loading an instance field must have the object instance first resolved. Even in an object instance, loading a static field is faster because no instance expression instruction is ever used. Please review the article on this topic.

Inline methods

Unlike the C++ language, the C# language does not allow you to suggest a method be inlined into its enclosing method call spots. Often, the .NET Framework is conservative here and will not inline medium-sized or large methods. However, you can manually paste a method body into its call spot.
Typically, this improves performance in micro-benchmarks, and it is really easy to do. However, it will make code harder to modify; it is only suggested for a very few, critical spots in programs.

Switch

You will find that the switch statement compiles in a different way than if-statements typically do. For example, if you use a switch on an int, you will often get jump statements, which are similar to a computed goto mechanism. Using jump tables makes switches much faster than some if-statements; please see the pertinent article for more details. Also, using a char switch on a string is very fast.

Flattened arrays

Using two-dimensional arrays in C# is relatively slow. However, you can explicitly create a one-dimensional array and access it through arithmetic that supposes it is a two-dimensional array. This is sometimes called flattening an array. You must use multiplication and addition to acquire the correct element address. Typically, this optimization will improve the performance of accessing any array, and it is used extensively on this site.

Jagged arrays

While flattened arrays are typically most efficient, they are sometimes very impractical. In these cases, you can use jagged arrays to improve the lookup performance. The .NET Framework enables faster accesses to jagged arrays than to 2D arrays. Please note that jagged arrays may cause slower garbage collections, because each jagged array element will be treated separately by the garbage collector.

StringBuilder

If you are doing significant appending of strings using the C# language, the StringBuilder type can improve performance. This is because the string type is immutable and can not be changed without reallocating the entire object. Sometimes, using strings instead of StringBuilder for concatenations is faster; this is typically the case when using very small strings or doing infrequent appends.

Char arrays

Using char arrays in your C# code is sometimes the fastest way to build up a string. Typically, you will combine char arrays with for-loops and character testing expressions. This logic is more painful to develop and test, but the time savings can be very significant, making certain routines more than ten times faster, while reducing memory allocations as well.

Byte arrays

In the C# language, the smallest unit of addressable storage is the byte type. You can store ASCII characters in a single byte, as well as small numbers. If you can store your data in an array of bytes, this allows you to save memory. For example, an array of characters or a string uses two bytes per character; an array of bytes can represent that data in one byte per character, result in about half the total memory usage.

Arrays

In the .NET Framework, you have many options for collections, such as the List type, and various other types such as ArrayList. While these types are convenient and should be used when necessary, it is always more efficient to use a simple array if this is possible.
The reason for this is that the more complex collections such as List are actually composed of internal arrays. They add logic to avoid the burden of managing the array size on each use. However, if you do not need this logic, or can adjust your code so that the logic is not needed, using an array will be faster.

Capacities

For collections in the .NET Framework and C# language, you can use an optional capacity argument to influence the intial buffer sizes. It is best to pass a reasonable parameter in most cases when creating a collection such as a Dictionary or List. This avoids many allocations when adding elements that were not anticipated. Please see the pertinent article on Dot Net Perls for details.

Rewrite loops

Here, we describe ways that you can rewrite the loops in your C# programs to improve performance. While the foreach loop can have good performance in many cases, it is best to use the for-loop in all performance-critical sections when possible. The reason for this is that not only do for-loops sometimes have better raw performance, you can often reuse the index variable (induction variable) to optimize other parts of the loop or method.
Typically, the while loop, the for loop and the do-while loop have the best performance. Also, it is sometimes beneficial—and sometimes harmful—to "hoist" the maximum loop variable outside of the for-loop statement.

 Consider structs
Unless you know more about the C# language than I do, it is typically best to avoid structs entirely. If you use structs, you must be careful to not pass the struct as a parameter to methods often, or performance will degrade to worse than using a class type. The reason for this is that structs are copied in their entirety on each function call or return value.
Structs can improve the performance of the garbage collector by reducing the number of distinct objects. Also, you can sometimes use separate arrays instead of arrays of structs, which can improve performance further.

Lookup tables

While switch statements or hashtables such as Dictionary in the C# language can provide good performance, using a lookup table is frequently the optimal choice. For example, instead of testing each character using logic when lowercasing a string, you can translate each character through a lookup table. The lookup table can be implemented as a character array. Another example is that you can implement the ROT13 algorithm with a lookup table, improving performance by more than two times.

Char argument

Often, you may need to pass a single character to a certain method in your programs. For example, the StringBuilder type allows you to append a single char; the Response.Write method also allows you to write a single char. It is more efficient to pass a char instead of a single-char string. The char is a value type, and is represented by two bytes, while a string is a reference type and requires over 20 bytes. This site contains an exploration of StringBuilder char argument performance.

Avoid ToString

In this tip, we assert that it is poor programming style to use the ToString method unnecessarily. Sometimes, developers will call ToString on a character in a string, and then test it against a single-character string literal. This is grossly inefficient; instead, use a character testing expression with two chars.
Please reference the specific article on this topic for more details here. The article shows this mistake results in code that is ten times slower than the correct approach.

Int string cache

Many C# programs use the ToString method on integer values frequently. Unfortunately, this requires an allocation on the managed heap for the new string. This will cause the next garbage collection to become slower. You can actually use a lookup table to optimize common cases for the integer ToString operation. This site demonstrates how this lookup table can make the ToString method thirty times faster.

IL Disassembler

For .NET development, you should be opening your methods with the IL Disassembler tool provided by Microsoft. This is a free tool and it provides an interface for you to view the MSIL (Microsoft Intermediate Language) output of all your compiled Release executables. It is sometimes useful to save copies of the intermediate language as you make changes, or to even count instructions.

Avoid sorting

Often, you can avoid performing a sort operation on an array or string simply by testing whether the input string or array is already sorted. Sometimes, this makes a big performance improvement. In other cases, this slows down your programs. Please see the article about checking alphabetical characters for more information.

Avoid string conversions

In this optimization tip, we note that you can actually avoid many string-based conversions. For example, you may need to ensure that a string is lowercased. If the string is already lowercase, you can avoid allocating a new string entirely. However, the framework ToLower method will not avoid this for you; you must manually test to see if no lowercasing is necessary, as with a for-loop over the characters.

Avoid Path methods

Unfortunately, the Path methods in the System.IO namespace are somewhat slow for many applications. Sometimes they can cause unnecessary allocations to occur, copying strings more than once. You can sometimes use character-based algorithms to minimize allocations, improving performance by nearly three times.

Dictionary

It is important that you use hashtables in your programs when appropriate. The Dictionary collection in the .NET Framework is not optimal in many cases, but provides good performance in many different situations. While we assume a fundamental knowledge of algorithms and searching here, the Dictionary is an essential tip in any performance article.

Read this site

The site you are reading, Dot Net Perls, contains a multitude of optimization experiments, often proven with benchmarks that provide times in nanoseconds per method call. Resources such as this site can be invaluable for certain tasks in programming; before Dot Net Perls came about, no such site had this information on optimization.

Compiler theory

While experimentation such as benchmarking and analyzing instructions generated can result in excellent program performance, without understanding the core theories of compilers you may be lacking knowledge about program performance. Unfortunately, compiler theory involves a great deal of advanced mathematics and can be very dense to start with.
My observation is that only a tiny minority of application developers have a significant knowledge of compiler theory; this topic may be more suitable to academic computer scientists and not rapid application development programmers. A good book on this subject is the dragon book.

Temporal locality

Another way you can optimize a program significantly is by rearranging it to increase temporal locality. This means that methods that act on a certain part of memory (such as the hard disk) are run at all once. You can find out more about this optimization here.

Misnomer

The term optimization is actually a misnomer in computer science. A program can never be truly optimized. Because compiler theory is undecidable, a program can never be proven to be optimally efficient—perhaps another approach is faster?

 Resources

There are many pages on this website that are focused on optimization tips. These pages are listed below; most of them show how you can rewrite a certain pattern of code to something arguably more efficient. Please be aware some of these optimizations result in code that is less maintainable.



















Wednesday, 25 January 2012

Development Tools(WCF)

WCF application can be developed by the Microsoft Visual Studio. Visual studio is available at different edition. You can use Visual Studio 2008 Expression edition for the development.
Visual Studio 2008 SDK 1.1

Microsoft Visual Studio 2008

Microsoft Visual studio 2008 provides new features for WCF compared to Visual Studio 2005. These are the new features added to VS 2008.


  1. Multi-targeting

    You can create application in different framework like Framework 2.0, 3.0 and 3.5
  2. Default template is available for WCF

  3. WCF - Test Client tools for testing the WCF service.

    Microsoft provides inbuilt application to test the WCF application. This can be done by opening the Visual Studio command prompt and type the wcfClient Serviceurl shows below. This will help the developer to test the service before creating the client application.

  4. WCF services can be debugged now in Visual Studio 2008. Wcfsvchost.exe will do it for you because service will be self hosted when you start debugging.

Run Redis.io DB as Windows Service

Run Redis.io DB as Windows Service

I recently started experimenting with Redis database (a NoSQL DB) as an alternative to SQL-Server for certain development requirements.
"Redis is an open source, advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets."
Since I do most of my development under Microsoft Windows, I was hoping to run my Redis instance on my Windows7 x64 Pro development desktop; more specifically, I wanted to run Redis as a Windows service.

Since Redis natively targets Linux/Unix environments, I went searching to see if there was a Windows port of the Redis database project that included the ability to run it as a service.  I found two open-source projects that, when combined, allow me to run Redis on Windows as a Service.

Running Redis DB on Win-7 x64

Installation Notes


The first thing I did was acquire a Windows port of the Redis server. I ended up using this project's compiled-version: https://github.com/kcherenkov/redis-windows-service. The project is described as:
"Windows 32 and x64 port of Redis server, client and utils.
It is made to be as close as possible to original unix version."
That "close as possible" statement mainly refers to how Redis commands that would (under Unix) rely on fork() to perform background operations are implemented as foreground operations (in Windows port).  But, for purposes of my software development and testing, this would suffice.  I can run my "production" instance of Redis on one of my Linux virtual machine instances (in particular, I have it running on OpenSuse 12.1 x64).

Get the Redis.io for Windows Build
To begin with, download the actual Redis.io (for windows) builds from here: https://github.com/dmajkic/redis/downloads (In my case, I selected the latest x64.zip build, which was redis-2.4.2-win32-win64-fix.zip).

Within that zip-archive, you will see two sub-directories: one is "32bit" and the other is "64bit".  Those zip file directories include the redis-server.exe and redis-cli.exe files (and redis.conf configuration file, etc).  Simply copy the contents of the archive's "64bit" (or 32bit) directory into the chosen directory where you will run Redis from. For example, I placed the x64 files into c:\Redis\

Theoretically, I simply needed to get the redis-server.exe running as a service now...


How to Install Redis DB as a Windows Service:

Win-7 x64 Installation Notes

OK, I have the Redis for Windows executables in my c:\Redis\ directory. Now it is time to get this database running as a Windows Service.  I found one such project that appeared active enough to merit consideration: (link) Run Redis as Service on Windows project on GitHub.

You need to download the compiled executable (RedisService.exe), which is available as a rather small (7 or 8KB) file on the "downloads" page for the project, and place it in your Redis directory.

Note: you may wish to reference this Microsoft site: using SC to create a service if you wish to understand in more detail what the upcoming commands I discuss are doing.

Although you may experience issues (as I will discuss next), you are now supposedly ready to install and start the RedisService.exe (from the command-line in a Windows console window) with the following command (note: alter the "Redis242" service-name to whatever makes sense for you as a process-label; also, change c:\redis portions to whatever directory location you chose):


sc create Redis242 start= auto DisplayName= Redis242 binpath= "\"C:\Redis\RedisService.exe\" C:\Redis\redis.conf"

IF the above statement *appears* to work, the service may or may not start when you execute the following:

sc start Redis242


But, if you experience some of what I did, the service may be failing for what I will call "hidden" reasons...

Fix Redis Windows Service Problems

and Potential Issues to Workaround

What I discovered with this RedisService.exe windows-service for Redis is that it is quite typical for open-source code: it makes a lot of assumptions and does little to provide proper dependency-testing and meaningful error-condition notification.

When you create the service (per above code: sc create ...) and/or try to start the service (using sc start) it may appear to just "hang" or otherwise take a very long time to attempt to start prior to failing with timeout errors.

The reason for redis-windows-service failing to start properly will be obfuscated, and here are some reasons why:
  • Starting the Service will throw 1053 (timeout) errors without indicating why, but one possible failure reason is that you must have the .NET Framework 4.0.30319 installed for this service to work.
  • Next, depending on your security setup (like my Windows-7 Pro security settings), you may need to tell Windows Firewall that it is OK for this process to act on your local network.  The easiest way to do this is run the redis-server.exe from the command-prompt and allow it access (to local network, through Firewall) when prompted.
  • Next, if you attempt run the redis-server again, you may see another (otherwise hidden) issue in that the executable is not from a "trusted source" or such: again, this issue can be resolved by choosing to allow this un-trusted process to run when provided the option.


After resolving this list of potential issues, you should be able to execute the sc create command and then perform an sc start redis242 (or whatever name you gave the service), to start the Redis Windows service and no longer experience a 1053 error due to timeouts caused by hidden reasons.

Redis Windows Service-Shutdown Problems

Note: there are problems with shutting down this service!  So far, the only way I have found to truly stop it is to reboot my system.  Also, when attempting to delete the service (sc delete redis242 or such), you will not be able to truly delete it as long as any Windows Service-Manager windows are open.

Once the RedisService.exe is installed and actually working, even "sc delete" requires a system reboot to take effect, since you can not otherwise truly stop the service.

The good news...
Although this service is problematic (as of when I wrote this tech blog entry), the program will run as a service and the client (redis-cli) can now be executed against the service-induced redis-server to test SET/GET of keys, etc.

If you are interested in accessing Redis.io from JavaScript, you may want to read my blog about NPM (Node Package Manager) where my example for installing a Nodejs module used a node-redis module.  I am able to access my Redis (NoSQL) DB from both Linux and Windows versions of Nodejs via the node-redis module's functionality from within Javascript.

 

Setup Apache Solr on Windows with Jetty Running as a Service via NSSM

Setup Apache Solr on Windows with Jetty Running as a Service via NSSM

Initial Solr Setup

  1. Install the latest Java JDK from http://www.oracle.com/technetwork/java/javase/downloads/index.html. Make sure to select 64bit version if you need it.
    Get Latest Java Image
  2. Download Solr 1.4.1 from one of the mirrors at http://www.apache.org/dyn/closer.cgi/lucene/solr/ (at the time of writing, not all mirrors seem to be hosting 1.4.1, but most seem to have at least 1.4.0)
    Solr Mirror Image
  3. Unzip the Solr download. You should have the files listed in the image below. Open the example folder.
    Unzip Solr Image
  4. Copy the etc, lib, logs, solr, webapps, and start.jar folders to C:\solr (you will need to create the folder at C:\solr)
    Copy to Root Image
  5. Now open the C:\solr\solr folder and copy the contents back to the root C:\solr folder. When you are done you can delete the C:\solr\solr folder.
    Copy Solr to Root Image
  6. At this point your C:\solr directory should look like the image below.
    How your Directory Should Look Image
  7. Solr can now be run at this point if you start it from the command line. Change your directory to c:\solr and then run: java -Dsolr.solr.home=c:/solr/ -jar start.jar <= slash direction seems to matter
    Start Solr Command Image
  8. If you go to http://localhost:8983/solr/ you should be greeted with the Welcome to Solr message.
    Welcome to Solr Image

Setup Jetty to Run as a Windows Service using NSSM

Now that Solr is up and running, we can work on getting Jetty to run as a Windows service. Since Jetty comes bundled with Solr, all we need is a way to run it as a service. There are several options to do this, but the one that I have found works the best and is the most compatible across windows environments is NSSM – the Non Sucking Service.
Once you download NSSM, open the win32 or win64 folder as appropriate and copy nssm.exe to your c:\solr folder.
Copy NSSM Image => NSSM exe Image
  1. Open an elevated command prompt and change the directory to C:\solr. and then run: nssm install Solr
    Install Solr Service Image
  2. A dialog will open. Select java.exe as the Application located at C:\Windows\System32\
  3. In the options input box enter: -Dsolr.solr.home=C:/solr/ -Djetty.home=C:/solr/ -Djetty.logs=C:/solr/logs/ -cp C:/solr/lib/*.jar;C:/solr/start.jar -jar C:/solr/start.jar
    NSSM exe Image
  4. Important! If you copy and paste the line above make sure to take out the line break.
  5. Click Install service. You should get a Service successfully installed message.
    Solr Service Installed Image
  6. Finally run: net start Solr
    Start Solr Command Image
  7. Jetty should now be running as a service. Check by going to http://localhost:/8983/solr
Not working? The best way to see what is going on is to stop the service and then run java.exe -Dsolr.solr.home=C:/solr/ -Djetty.home=C:/solr/ -Djetty.logs=C:/solr/logs/ -cp C:/solr/lib/*.jar;C:/solr/start.jar -jar C:/solr/start.jar from the C:\Windows\System32\ folder and review all the log information in the output.

 

Writing code C# Performace

Writing code C# Performace

Writing code that runs quickly is sometimes at odds with writing code quickly. C.A.R. Hoare, computer science luminary and discoverer of the QuickSort algorithm, famously proclaimed, "Premature optimization is the root of all evil." The extreme programming design principle of "You Aren't Gonna Need It" (YAGNI) argues against implementing any features, including performance optimizations, until they're needed.
Writing unnecessary code is undoubtedly bad for work efficiency. However, it's important to realize that different situations have different needs. Code for vehicular real-time control systems has inherent up-front responsibilities for stability and performance that aren't present in, say, a small one-off departmental application. Therefore, it's more important in such code to optimize early and often.
Performance tuning for real-world applications often involves activities geared towards finding bottlenecks: in code, in the network transport layer, and at transaction boundaries. However, these techniques alone cannot solve the dreaded problem of uniformly slow code, which surfaces when large bottlenecks have been resolved but the code still exhibits inadequate performance. This is code that has been written without attention to correct usage, often by junior programmers, in the same style across whole modules or applications. Unfortunately, the best solution for this problem is to make sure that all programmers on a project follow correct coding practice when writing the code the first time; coding guidelines and good shared libraries help enormously.
This article presents helpful tips for writing in-process .NET managed code that performs well. It's assumed that basic programming skills such as factoring control structures, pulling work outside of loops whenever possible, caching variables for reuse, use of the switch statement, and the like are known to the average reader.
All code examples referred to in this article can be downloaded from the .NET Developer's Journal Web site, at www.sys-con.com/dotnet/sourcec.cfm. The code comes with a Windows Forms application that can be used to easily view the code and run all the tests on your own machine. You'll need the .NET Runtime 1.1 to run the code.
Tools
While testing tools such as NUnit and the upcoming VS.NET 2005 Team System can help you find bottlenecks, when tuning small sections of code, there's still no substitute for the micro-benchmark. This is because most generic testing frameworks depend on things like delegates, attributes, and/or interface method calls to do testing, and the code usually is not written with benchmarking primarily in mind. This can be very significant if you're interested in measuring the execution time of a batch of code down to the microsecond or even nanosecond level.
A micro-benchmark consists of a tight loop isolating the code that's being tested for performance, with a time reading before and after. When the test has finished, the start time is subtracted from the end time, and this duration is divided by the number of iterations to get the per-iteration time cost. The following code shows a simple micro-benchmark construct:


int loopCount = 1000000000;
long startTime, endTime;
double nanoseconds;

startTime = DateTime.Now.Ticks * 100;
for(int x = 0; x < loopCount; x++) {
  // put the code to be tested here
}
endTime = DateTime.Now.Ticks * 100;
nanoseconds = ((double)(endTime - startTime)) / ((double)loopCount);
Console.WriteLine(nanoseconds.ToString("F") + " ns per operation");
When performing a simple micro-benchmark, it's important to remember a couple of things. First, small fluctuations (noise) are normal, so to obtain the most accurate results, each test should be run several times. In particular, the first set of tests executed after program initialization may be skewed due to the lazy acquisition of resources by the .NET runtime. Also, if your results are very inconsistent, you may not have penetrated the "noise floor" of the measurement. The best solution for this is to increase the number of loops and/or tests. Another thing to remember is that looping itself introduces overhead, and for the most accurate readings, you should subtract this from the result. On a P4-M 2-GHz laptop, the per-loop overhead for a for loop with an int counter in release mode is around 1 nanosecond.
I'd never advocate running each code fragment from a long program through micro-benchmarks, but benchmarking is a good way to become familiar with the relative costs of different types of expressions. True knowledge of the performance of your code is built on actual observations. As time goes on, you'll find yourself needing such tests less and less, and you'll keep track in the back of your head of the relative performance of the statements you're writing.
Another important tool is ildasm.exe, the IL disassembler. With it, you can inspect the IL of your release builds to see if your assumptions are correct about what's going on under the covers. IL is not hard to read for a person familiar with the .NET framework; if you're interested in learning more, I suggest starting with Serge Lidin's book on the subject.
A great free tool for decompiling IL to C# or VB source, Reflector, is found at www.aisto.com/roeder/dotnet/; it's incredibly useful for viewing code that ships with the .NET Framework, for those of you less familiar with IL.
The CLR Profiler, available as a free download from Microsoft's Web site, allows you to track memory allocation and garbage collection activity, among other useful features. Also, the MSDN Web site has excellent coverage of performance metrics tools such as WMI and performance counters.
Working with Objects and Value Types
Objects: A Double Whammy
Objects are expensive to use, partly because of the overhead involved in allocating memory from the heap (which is actually well-optimized in .NET) and partly because every created object must eventually be destroyed. The destruction of an object may take longer than its creation and initialization, especially if the class contains a custom finalization routine. Also, the garbage collector runs in an indeterministic way; there's no guarantee that an object's memory will be immediately reclaimed when it goes out of scope, and until it's collected, this wasted memory can adversely affect performance.
The Garbage Collector in a Nutshell
It's necessary to understand garbage collection to appreciate the full impact of using objects. The single most important fact to know about the garbage collector is that it divides objects into three "generations": 0, 1, and 2. Every object starts out in generation 0; if it survives (if at least one reference is maintained) long enough, it goes to 1; much later, it transitions to 2. The cost of collecting an object increases with each generation. For this reason, it's important to avoid creating unnecessary objects, and to destroy each reference as quickly as possible. The objects that are left will often be long-lived and won't be destroyed until application shutdown.
Lazy Instantiation/Initialization
The Singleton design pattern is often used to provide a single global instance of a class. Sometimes it's the case that a particular singleton won't be needed during an application run. It's generally good practice to delay the creation of any object until it's needed, unless there's a specific need to the contrary - for instance, to pre-cache slow-initializing objects such as database connections. The "double-checked locking" pattern is useful in these situations, as a way to avoid synchronization and still ensure that a needed action is only performed once. Lazy initialization is a technique that can enhance the performance of an entire application through object reduction.
Avoiding Use of Class Destructors
Class destructors (implemented as the Finalize() method in VB.NET) cause extra overhead for the garbage collector, because it must track which objects have been finalized before their memory can be reclaimed. I've never had a need for finalizers in a purely managed application.
Casting and Boxing/Unboxing Overhead
Casting is the dynamic conversion of a type at runtime to another, and boxing is the creation of a reference wrapper for a value type (unboxing being the conversion back to the wrapped value type). The overhead of both is most heavily felt in collections classes, as they all - with the exception of certain specialized ones like StringDictionary - store each value as an Object. For instance, when you store an Int32 in an ArrayList, it is first boxed (wrapped in an object) when it is inserted; each time the value is read, it is unboxed before it is returned to the calling code.
This will be fixed in the next version of .NET with the introduction of generics, but for now you can avoid it by creating strongly typed collections and by typing variables and parameters as strongly as possible. If you're unsure about whether or not boxing/unboxing is taking place, you can check the IL of your code for appearances of the box and unbox keywords.
Trusting the Garbage Collector
Programmers new to .NET sometimes worry about memory allocation to the point that they explicitly invoke System.GC.Collect(). Garbage collection is a fairly expensive process, and it usually works best when left to its own devices. The .NET garbage collection scheme can intentionally delay reclamation of objects until memory is available, and in particular longer-lived objects (those that make it to generation 1 or 2) may not be reclaimed for an extended period. Even a simple "Hello, world!" console application may allocate 15 MB or more of memory for its "working set." My advice: don't call GC.Collect() unless you really know what you're doing.
Properties, Methods, and Delegates
Avoiding Overuse of Property Getters and Setters
Most people don't realize that property getters and setters are similar to methods when it comes to overhead; it's mainly syntax that differentiates them. A non-virtual property getter or setter that contains no instructions other than the field access will be inlined by the compiler, but in many other cases, this isn't possible. You should carefully consider your use of properties; from inside a class, access fields directly (if possible), and never blindly call properties repeatedly without storing the value in a variable. All that said, this doesn't mean that you should use public fields! Example 1 demonstrates the performance of properties and field access in several common situations.
About Delegates
Delegates are slower to execute than interface methods. Delegates are often used to introduce a level of indirection in code, but in almost all cases interfaces allow a cleaner design. Of course, it's impossible to completely shun delegates; the entire event-handling paradigm in .NET is based on them. Example 2 compares the performance of delegates and direct method calls.
Minimizing Method Calls
The .NET compiler is capable of performing many optimizations for release builds. One of them is called "method inlining." If method A calls method B and certain other conditions are met, such as the code in method B being small enough, the code from B will be copied into A during compilation. However, .NET won't or can't inline certain types of methods, such as virtual methods or methods over a certain size. Each method invocation/property access entails significant overhead, such as the allocation of a stack frame, etc. Of course, you should never repeatedly call a method for the same result on purpose, but you should also be mindful of the impact of method calls in general.

Optimize Code C#

1. Knowing when to use StringBuilder

You must have heard before that a StringBuilder object is much faster at appending strings together than normal string types.
The thing is StringBuilder is faster mostly with big strings. This means if you have a loop that will add to a single string for many iterations then a StringBuilder class is definitely much faster than a string type.
However if you just want to append something to a string a single time then a StringBuilder class is overkill. A simple string type variable in this case improves on resources use and readability of the C# source code.
Simply choosing correctly between StringBuilder objects and string types you can optimize your code.

2. Comparing Non-Case-Sensitive Strings

In an application sometimes it is necessary to compare two string variables, ignoring the cases. The tempting and traditionally approach is to convert both strings to all lower case or all upper case and then compare them, like such:
str1.ToLower() == str2.ToLower()
However repetitively calling the function ToLower() is a bottleneck in performace. By instead using the built-in string.Compare() function you can increase the speed of your applications.
To check if two strings are equal ignoring case would look like this:
string.Compare(str1, str2, true) == 0 //Ignoring cases
The C# string.Compare function returns an integer that is equal to 0 when the two strings are equal.

3. Use string.Empty

This is not so much a performance improvement as it is a readability improvement, but it still counts as code optimization. Try to replace lines like:
if (str == "")
with:
if (str == string.Empty)
This is simply better programming practice and has no negative impact on performance.
Note, there is a popular practice that checking a string's length to be 0 is faster than comparing it to an empty string. While that might have been true once it is no longer a significant performance improvement. Instead stick with string.Empty.

4. Replace ArrayList with List<>

ArrayList are useful when storing multiple types of objects within the same list. However if you are keeping the same type of variables in one ArrayList, you can gain a performance boost by using List<> objects instead.
Take the following ArrayList:
ArrayList intList = new ArrayList();
intList.add(10);
return (int)intList[0] + 20;
Notice it only contains intergers. Using the List<> class is a lot better. To convert it to a typed List, only the variable types need to be changed:
List<int> intList = new List<int>();

intList.add(10)

return intList[0] + 20;
There is no need to cast types with List<>. The performance increase can be especially significant with primitive data types like integers.

5. Use && and || operators

When building if statements, simply make sure to use the double-and notation (&&) and/or the double-or notation (||), (in Visual Basic they are AndAlso and OrElse).
If statements that use & and | must check every part of the statement and then apply the "and" or "or". On the other hand, && and || go thourgh the statements one at a time and stop as soon as the condition has either been met or not met.
Executing less code is always a performace benefit but it also can avoid run-time errors, consider the following C# code:
if (object1 != null && object1.runMethod())
If object1 is null, with the && operator, object1.runMethod()will not execute. If the && operator is replaced with &, object1.runMethod() will run even if object1 is already known to be null, causing an exception.

6. Smart Try-Catch

Try-Catch statements are meant to catch exceptions that are beyond the programmers control, such as connecting to the web or a device for example. Using a try statement to keep code "simple" instead of using if statements to avoid error-prone calls makes code incredibly slower. Restructure your source code to require less try statements.

7. Replace Divisions

C# is relatively slow when it comes to division operations. One alternative is to replace divisions with a multiplication-shift operation to further optimize C#. The article explains in detail how to make the conversion.

8. Boxing and UnBoxing

Variables that are based on value types directly contain values. Variables of reference types (referred to as objects) store references to the actual data and should be used to define the behavior of your application. On occasion, programmers make method calls passing a value type where a reference type is expected. To handle this situation C# uses boxing. Boxing converts a value type to a reference type and consists of two operations:
  • Allocating an object instance (on the heap).
  • Copying the value-type value into that instance.


The box contains the copy of the value type object and duplicates the interfaces implemented by the boxed value type. When you need to retrieve anything from the box, a copy of the value gets created and returned, called unboxing. That’s the key concept of boxing and unboxing. A copy of the object goes in the box, and another gets created whenever you access what’s in the box. The major issue with boxing and unboxing is that it happens automatically. Every type in C#, including the intrinsic types, is derived from Object and may be implicitly cast to an object. The following code is an example of commonly used constructs that cause boxing operations with value types.

int i = 15;

int j = 25;

Console.WriteLine(“Print values: {0}, {1}”, i, j);

This may seem like a trivial amount of overhead at first glance. However, given enough of these statements scattered throughout your application, you'll soon discover that the overhead quickly becomes substantial. In addition to the heap allocation and copy operation performed when boxing, there's overhead in maintaining the heap-based object, such as reference tracking, heap compaction, and garbage collection. This is what the code looks like to the compiler.

int i = 15;

     int j = 25;

     object obj1 = i;

     object obj2 = j;

     Console.WriteLine("Print values: {0}, {1}", obj1.ToString(), obj2.ToString());

You would never write the code as listed above, but that is what you are doing by letting the compiler automatically convert from a specific value type to System.Object. You could modify the previous code to avoid the implicit boxing and unboxing by using the ToString method as shown below.

Console.WriteLine("Print values: {0}, {1}", i.ToString(), j.ToString());

Using arrays to store a collection of value types is a common area where boxing can hurt application performance. If you intend to work with ArrayList, for example, do not declare your data type as struct (Value type) because ArrayList works with Object (Reference type) and every time you add an instance of the struct or run over the container, in a loop, a boxing process will occur.

9. ‘as’ versus type casting

As good programming practice we try to avoid coercing one type into another when we can. But sometimes, runtime checking is simply unavoidable. When you have to cast an object into another type you have a couple of choices: the as operator or casting. You should use the as operator whenever you can because it is safer and more efficient at runtime.

Using traditional casting you could write something like the following.

object o = new MyObject();

    try

    {

     MyType m;

m = (MyType)o;

if (m != null)

 {

         //work with m as a MyType object

      }

else

     {

         //Report null reference failure

     }

    }

    catch

    {

         //report the conversion failure

    }

Instead we will use the as operator as an alternative and produce simpler and easier to read code.

    object o = new MyObject();

MyType m = o as MyType;

if (m != null)

he as operator is similar to a cast operation; however, there are two advantages to using the as operator.

  •     It makes your code more     readable.    
  •     If a type mismatch occurs,     the object will become null instead of throwing an exception.

Note: Using the as operator instead of casting only works for reference types.