0

Length Vs Count Vs Initialized Variable in C#

Length Vs Count Vs Initialized Variable in C#

This test originated from having to loop over millions of records in an array in an application that requires everything be as fast as possible. It was stumbled upon by accident when I accidentally used a variable for a loop construct instead of the actual length property.

 

Every programmer typically writes looping constructs similar to:

But what happens if the loop was tweaked slightly? That is, instead of checking the Length or Count property every iteration, we instead checked a variable initialized to the size of the array or list?

So that’s when this Curious Consultant started wondering what’s faster? Length Vs Count vs Initialized Variable in C# looping constructs.

Let’s check it out!

 

The Nuts and Bolts

To start with, two basic arrays of ints and strings were chosen as they’re easy to generate and provide us some simple constructs.

 

Next, I chose to create an array of Dictionary objects and a List of Dictionary objects. This would provide a little bit more sizeable memory operations.

 

Lastly, to balance things out, I chose to create a List of ints.

 

The code is written in Visual Studio 2017 targeting .Net Framework version 4.7.1 x64. The source code is available at the end of this blog so you can benchmark it on your own system.

 

In a nutshell, the code does the following:

  1. Creates the list, arrays, and dictionaries, pre-sizing them where possible so no timing operations are spent generating or increasing the size of said objects.
  2. Loops through each object twice: the first time with the Length or Count property; the second time using an int variable initialized to the size of the Array or List object.

 

Assumptions:

  • No exception handling as no exceptions should occur
  • The sizes of the arrays or list would not change through the loop

 

The exe file was run under Windows 10 Professional 64-bit with 16GB of memory.

 

The test was run for the following Array/List sizes:

  • 500
  • 80,000
  • 6,000,000
  • 30,000,000

 

Locked and Loaded!

These tests were run 3 times, with the average of the 3 runs calculated.

All times are indicated in seconds.milliseconds format. Lower numbers indicate faster run time performance.

Winners are highlighted in green; there are no points for second place.

 

The Results Speak for Themselves:

With two exceptions, using the variable initialized to the size won hands down in every instance.

 

Number of Items

 

500

80,000

6,000,000

30,000,000

int[] length

00.0000024

00.0000898

00.0048867

00.0241620

int[] variable

00.0000010

00.0000770

00.0040654

00.0205747

 

string[] length

00.0000006

00.0000645

00.0042335

00.0187586

string[] variable

00.0000005

00.0000233

00.0017314

00.0086074

 

Dictionary<string, DateTime>[] length

00.0000007

00.0001147

00.0072403

00.0416102

Dictionary<string, DateTime>[] variable

00.0000009

00.0001077

00.0044890

00.0186091

 

List<int>() count

00.0000005

00.0001996

00.0185924

00.0796033

List<int>() variable

00.0000023

00.0001280

00.0091754

00.0411283

 

List<Dictionary<string, DateTime>>() count

00.0000097

00.0002217

00.0191115

00.0818092

List<Dictionary<string, DateTime>>() variable

00.0000019

00.0001371

00.0099309

00.0472050

 

In Summary:

Up to 30 million records, the time differences aren’t significant enough for an every day user to notice.

However, if there’s a need or requirement to micro-optimize, squeezing out every last little microsecond possible, then that’s the way to go.

 

The Code:

 

David Lozinski