C# Speed

Microsoft .NET Framework, ASP.NET, Visual C# (CSharp, C Sharp, C-Sharp) Developer Training, Visual Studio


Jump to: navigation, search
CSharp-Online.NET:Tutorials
C# Tutorials
C# Speed
edit

Contents


The first thing most people say when you mention .Net, is how slow it is; but this is rather unfair for the language as a whole. Ok, so it is slightly slower than your fully precompiled languages. However, applications which grind to an unusable halt are not the fault of .Net, but instead how the programmers have decided to implement the .Net classes.

The basic rule - GUI lives on

The most simplistic way of keeping application speed up is to ensure that no blocking calls are made on the same thread as the GUI. As soon as users see the GUI failing to redraw they will be at task manager pretty quickly and if not chances are they’ll be finding a spare pen that they can poke that reset switch with.

Scenario

The scenario is that an application must carry out some heavy processing but still let the user their PC.

Note that as multicore processors become more and more common noticing issues with the responsiveness of the PC will be very difficult without monitoring the cores usage levels.

Example - Initial problem

To simplify this scenario as much as possible the following form and code is used.


Image:SpeedGUITestForm.gif


private void button1_Click(object sender, EventArgs e)
{
  doHeavyProcessing();
}
 
private void doHeavyProcessing()
{
  float x = 4;
 
  for (int i = 0; i < 10000000; i++)
  {
    x /= DateTime.Now.Millisecond;
  }
}
 
private void button2_Click(object sender, EventArgs e)
{
  MessageBox.Show("I'm multitasking!");
}

Results - Initial problem

What you will find with this code is that it will lock the processor for approximately 10 seconds, although this speed will vary greatly depending on the specs of your PC. If you find that the time is too short just increase the number of iterations. Notice by looking at Task Manager that the processor is at a constant 100%.


Image:SpeedSingleProcessorLock.gif


The problem here is that if you click on the 'Multitask..' button then nothing will happen the event is ignored and pretty soon the title text will be appended with “(Not Responding)”. What’s even worse with this is that the rest of the OS will grind to a halt until your application has completed its heavy processing load and may even crash the OS depending on the other applications waiting for their turn to do some processing.


Example - Simple solution

This next solution although doesn’t solve the loss of interactivity for your application does reduce both the load on the processor and the risk of crashing the OS.

private void doHeavyProcessing()
{
  const int SLEEP_PERIOD = 20;
  const int ITTERATION_RELOAD = 100000;
  int itterationsTillRelax = ITTERATION_RELOAD;
 
  float x = 4;
 
  for (int i = 0; i < 10000000; i++)
  {
    x /= DateTime.Now.Millisecond;
 
    if (--itterationsTillRelax == 0)
    {
      itterationsTillRelax = ITTERATION_RELOAD;
      System.Threading.Thread.Sleep(SLEEP_PERIOD);
    }
  }
}

Here a Sleep command is being sent to the current thread after a particular number of iterations of the loop. This method has been used to avoid splitting up the ‘algorithm’ as in many practical situations the algorithm cannot be easily split. Notice how the counter is being reloaded, both the counter reload number and the sleep period can be adjusted to suit the applications need.

Results - Simple solution

Image:SpeedSingleProcessorUsage.gif


Example - Ultimate solution

To allow your user to continue using your application you must put the processing on a totally separate thread, the easiest way of doing this is to create a delegate for the type of method you want to call. The required changes are shown below.

public delegate void simpleMethodCall();
 
private void button1_Click(object sender, EventArgs e)
{
  simpleMethodCall myMethod = new simpleMethodCall(doHeavyProcessing);
  myMethod.BeginInvoke(null, null);
}
BeginInvoke must be used to call the method on an asynchronous thread. If Invoke is used only a synchronous call will be made and so the problem will still remain as in the previous example.

Results - Ultimate solution

Your application will now allow users to continue using it. It is important to remember that your processor usage will still be at the same level as in the previous example.

Image:SpeedFormWorking.gif


Advanced methods


Personal tools