Compare performance looping over DateTime and integer variables in C#


The example Find Friday the Thirteenths in C# doesn’t really worry about performance. It uses integers to loop over the dates within a range. For every year between the start and end dates, the code considers the 13th of each month in that year. It then ignores any months before the start date and ends the loop if it finds a date after the end date. It’s a short loop so performance doesn’t matter much.

This method works and is reasonably fast but it makes sense to wonder if it would be more efficient to not need to test every date to see if it is before the start date or after the end date.

The following code shows how this example compares the performance of two types of loops over a range of dates.

// Compare two methods for looping over the dates.
private void btnGo_Click(object sender, EventArgs e)

    // Test variables.
    DateTime loop_start_time;
    TimeSpan elapsed;
    bool test_bool;

    // Get the start and end date components.
    DateTime start_date = dtpStart.Value.Date;
    DateTime end_date = dtpEnd.Value.Date;
    int start_year = start_date.Year;
    int end_year = end_date.Year;

    // *** Loop by using int variables. ***
    // Loop over the selected years.
    loop_start_time = DateTime.Now;
    for (int year = start_year; year <= end_year; year++)
        // Loop over the months in the year.
        for (int month = 1; month <= 12; month++)
            // See if this month's 13th is a Friday.
            DateTime test_date = new DateTime(year, month, 13);

            // If we haven't reached the start date, skip this one.
            if (test_date < start_date) continue;

            // If we've passed the end date, stop looping.
            if (test_date > end_date) break;

            // See if this is a Friday.
            test_bool = (test_date.DayOfWeek == DayOfWeek.Friday);
    elapsed = DateTime.Now - loop_start_time;
    txtIntLoop.Text = elapsed.TotalSeconds.ToString("0.0000") + " secs";

    // *** Loop by using a DateTime variable. ***
    // Find the first 13th date >= start_date.
    DateTime loop_start =
        new DateTime(start_year, start_date.Month, 13);
    if (loop_start < start_date) loop_start.AddMonths(1);

    // Find the last 13th date <= end_date.
    DateTime loop_end = new DateTime(end_year, end_date.Month, 13);
    if (loop_end > end_date) loop_end.AddMonths(-1);

    // Time the first loop.
    loop_start_time = DateTime.Now;
    for (DateTime loop_date = loop_start;
        loop_date < loop_end;
        loop_date = loop_date.AddMonths(1))
        test_bool = (loop_date.DayOfWeek == DayOfWeek.Friday);
    elapsed = DateTime.Now - loop_start_time;
    txtDateTimeLoop.Text =
        elapsed.TotalSeconds.ToString("0.0000") + " secs";

The code creates some variables to record start and elapsed times and then gets some information about the selected start and end dates. It then uses integers to represent the years and months in the date range and ignores any dates that fall outside of the range. See the previous example for more information on how that loop works.

Next the code calculates the first 13th of the month greater than or equal to the start date and the last 13th of the month before or equal to the end date. It then uses a DateTime variable to loop over the dates between the start 13th and the end 13th. After each iteration, the loop’s iteration section uses the DateTime variable’s AddMonth method to add 1 month to the variable, making it move to the 13th of the following month.

You can see from the picture that the code that uses integers for looping has better perrformance than the code that uses a DateTime looping variable. The difference presumably is because the AddMonths method takes longer than creating a new DateTime from integer parameters. (If you make a simple test program that compares a loop that uses AddMonths and another that create new integers, you’ll see that this seems to be the case.)

Download Example   Follow me on Twitter   RSS feed   Donate

This entry was posted in performance, syntax and tagged , , , , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.