Tek Eye Logo

Tek Eye

Measuring Code Execution Time in C Sharp

Occasionally, part of a programmers job, once the basic functionality of an app is up and running, is to consider code performance. One task in speeding up an app is to see which parts run slower than others. Whilst .NET does support performance counters, basic timing of code execution can be done with the .NET Stopwatch class.

Timing with the C# Stopwatch

Using the .NET Stopwatch to Measure Code Execution Time

In this example a .NET Stopwatch is used to time the sorting of a list of numbers. The example timing code provided in this tutorial is in a basic WinForms app. After starting a new WinForms project in Visual Studio, open the starting form. Then use System.Diagnostics to access the .NET Stopwatch:

using System.Diagnostics;

Create an instance of the Stopwatch for use in the program:

Stopwatch sw = new Stopwatch();

A list of integers is going to be generated and stored in a List collection, plus another collection is going to be used to reset the orginal list. The backup list is going to be used so that the sort can be run several times. This is to illustrate a variation in .NET execution time that often happens for a first run of code:

//Number of random numbers
const int NUMBER_OF_NUMBERS = 100;
//To store some random numbers
List<int> Integers = new List<int>(NUMBER_OF_NUMBERS);
//Store a backup for resetting
List<int> Backup;

In the forms constructor generate the numbers to sort, here using the Random class:

//Generate a list of numbers
//Random number generator
Random Rng = new Random();
for (int i = 0; i < NUMBER_OF_NUMBERS; i++)
    Integers.Add(Rng.Next());
Rng = null;

Then backup the list for later list resetting:

Backup = new List<int>(Integers);

A ListBox is dropped onto the form to display the numbers:

listBox1.DataSource = Integers;

Drop a Button onto the form, when clicked it will do the sort and update the display:

private void button1_Click(object sender, EventArgs e)
{
    Integers.Sort();
    //Update display
    listBox1.DataSource = null;
    listBox1.DataSource = Integers;
}

To time the sort wrap the call in a Stopwatch Start() and Stop():

sw.Start();
Integers.Sort();
sw.Stop();

The ElapsedTicks of the Stopwatch gives a count of how many processor ticks occurred. The Frequency of the Stopwatch gives the number of ticks per second. Thus, the time is ElapsedTicks/Frequency, converted to double to avoid division issues:

double elapsedTime = (double)sw.ElapsedTicks / (double)Stopwatch.Frequency;

This will be a small number with our modern processors, therefore, convert it to microseconds by multiplying by 1,000,000 (or milliseconds by times 1,000), makes for easy reading:

string executionTime = (elapsedTime * 1000000).ToString("F2") + " microseconds";

Drop a ListBox onto the form to display the timings:

listBox2.Items.Add(executionTime);

Reset the Stopwatch ready for the next thing to time:

sw.Reset();

To run the sort several times, add another button to restore the original list to its initial starting condition:

private void button2_Click(object sender, EventArgs e)
{
    //Reset to original random list
    Integers = new List<int>(Backup);
    listBox1.DataSource = Integers;
}    

Here is the code's first run showing the unsorted numbers:

Timing Demo Start

Here is the timing of the sort execution. The code was run on a PC with an i7-4770 3.4 GHz Intel CPU that produces 3,312,657 ticks per second (the number of ticks will vary by CPU). The timings list shows several runs of the sort (using the sort and reset buttons several times):

Code execution timing

Notice that there is a variation in the time taken to execute the sort function, especially the first sort. Variation in code execution times is down to several factors. Those factors can include one or many of the following (though not all of the following applies in the simple example shown here):

  • The data being processed
  • Windows and .NET memory caching
  • .NET JITing
  • Garbage collection
  • The Windows operating systems (OS) running other tasks (Windows is not a real-time operating system)
  • Disk caching
  • CPU caching
  • Accessing system resources (disks, network, Internet, databases, etc.)

When looking to speed up code use the timings after the first pass has executed. If first run time is important then Ngen can be used to reduce the start time.

Full Timing Execution Example Code

Here is the full code for the form used to demonstrate the timing of executing code:

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Diagnostics;

namespace ExecutionTiming
{
    public partial class Form1 : Form
    {
        Stopwatch sw = new Stopwatch();
        //Number of random numbers
        const int NUMBER_OF_NUMBERS = 100;
        //To store some random numbers
        List<int> Integers = new List<int>(NUMBER_OF_NUMBERS);
        //Store a backup for resetting
        List<int> Backup;

        public Form1()
        {
            InitializeComponent();
            //Generate a list of numbers
            //Random number generator
            Random Rng = new Random();
            for (int i = 0; i < NUMBER_OF_NUMBERS; i++)
                Integers.Add(Rng.Next());
            Rng = null;
            //Back up the unsorted list for reseting later
            Backup = new List<int>(Integers);
            //Display the list to sort
            listBox1.DataSource = Integers;
        }
        //Sort the list and time the sort
        private void button1_Click(object sender, EventArgs e)
        {
            sw.Start();
            Integers.Sort();
            sw.Stop();
            //Calculate elapsed time
            double elapsedTime = (double)sw.ElapsedTicks / (double)Stopwatch.Frequency;
            //Convert to a string
            string executionTime = (elapsedTime * 1000000).ToString("F2") + " microseconds";
            //Show the execution time
            listBox2.Items.Add(executionTime);
            //Reset the stopwatch ready for next timing
            sw.Reset();
            //Update sort display
            listBox1.DataSource = null;
            listBox1.DataSource = Integers;
        }
        //Reset to the original unsorted list
        private void button2_Click(object sender, EventArgs e)
        {
            //Reset to original random list
            Integers = new List<int>(Backup);
            //Show the unsorted list again
            listBox1.DataSource = Integers;
        }
    }
}

See Also

Author:  Published:  

ShareSubmit to TwitterSubmit to FacebookSubmit to Google+Submit to LinkedInSubmit to redditPrint Page

markdown CMS Small Logo Icon ↓markdown↓ CMS is fast and simple. Build websites quickly and publish easily. For beginner to expert.



Articles on:

Android Programming and Android Practice Projects, HTML, VPS, Computing, IT, Computer History, ↓markdown↓ CMS, C# Programming, Using Windows for Programming



Free Android Projects and Samples:

Android Examples, Android List Examples, Android UI Examples