0

Faster to Trim during or after assignment in C# .Net

Faster to Trim during or after assignment in C# .Net

Does it make a difference if you Trim() during or after assigning a value to a variable in C# .Net? Which was is faster? Which object, string or StringBuilder, is faster?

This test stemmed from a project with production code that processed thousands of strings. While doing so, it trimmed each one of its whitespace.

Here’s the gist of the code:

Then as I was rereading the code one day, it occurred to me to try it like this:

as it should hypothetically use less resources since it’s not first allocating temp_str, and then reallocating temp_str for the trim() operation.

So that’s when this curious consultant started wondering… is it faster to trim during or after assignment in C# .Net?

The Set Up:

I wrote a C# Console application to test several methods. The code is written in Visual Studio 2012 targeting .Net Framework version 4.5 x64. The source code is available at the end of this blog so you can benchmark it on your own system if you wish.
 
In a nutshell, the code does the following:

  1. Creates an array of Guids, converted to strings, and padded on the left, right, or both sides with white space.
  2. Assigns the string to either a string or StringBuilder object:
    1. a. while performing an inline Trim()
    2. b. Or doing the trim after the assignment

Only single-threaded for-loops are used because I’m just interested in raw conversion speeds, not the fastest way to loop through arrays.
 
The exe file was installed and run on an Alienware M17X R3 running Windows 7 64-bit with 16 GB memory on an i7-2820QM processor.
 
The test was run for the following comparisons:

  • Trimming 2,147, 214,748, and 21,474,836 strings during the assignment to another string.
  • Trimming 2,147, 214,748, and 21,474,836 strings after the initial assignment to another string.
  • Trimming 2,147, 214,748, and 21,474,836 strings during the assignment to a StringBuilder object.
  • Trimming 2,147, 214,748, and 21,474,836 strings after the initial assignment to a StringBuilder object.

 

The Runs:

Before starting, my hypothesis was that I expected the trim during the initial assignment to run faster with both strings and StringBuilder objects.
 
Let’s see what happened on my machine.
 
All times are indicated in minutes:seconds.milliseconds format. Lower numbers indicate faster runtime performance.
 
Winners are highlighted in green.
 

Run #1

Number of string assignments:

 

2,147

214,748

21,474,836

Target is a STRING

 

 

 

    Trim() during assignment

00:00.00

00:00.0468001

00:21.8329953

    Trim() after initial assignment

00:00.00

00:00.0468001

00:19.3908340

 

 

 

 

Target is a STRINGBUILDER

 

 

 

    Trim() during assignment

00.00.00

00:00.1092001

02:04.9167826

    Trim() after initial assignment

00:00.00

00:00.2028004

00:47.0184825

 

Run #2

Number of string assignments:

 

2,147

214,748

21,474,836

Target is a STRING

 

 

 

    Trim() during assignment

00:00.00

00:00.0468000

00:21.1692372

    Trim() after initial assignment

00:00.00

00:00.0468001

00:18.7824330

 

 

 

 

Target is a STRINGBUILDER

 

 

 

    Trim() during assignment

00.00.00

00:00.1092002

02:07.7918767

    Trim() after initial assignment

00:00.00

00:00.2028003

00:47.5332834

 

The Results:

Wow talk about a flip-flop depending on how many strings or StringBuilder objects being manipulated. So it seems from the results for both a string and StringBuilder it’s best to:

  1. Do either up to a few thousand trims
  2. Only do the trim during an assignment when a few hundred thousand are involved
  3. A million or more? Definitely should use the .Trim() after the assignment.

Even more surprising is why does the StringBuilder object take soooooooo loooooooong with the Trim() during an assignment?
 
And why does a Stringbuilder take soooooo looooong to trim afterwards?
 
Can any .Net coders shed light on this?
 
With results like these, one has to question why use a StringBuilder at all?
 

In Summary:

On my system, unless someone spots a flaw in my test code, it appears the time difference is so negligible when the final destination is a string object it doesn’t matter which way you go. This method holds its ground for both a very few .Trim operations (which I suspect most programmers face), or several million at once. So unless you need those 2 seconds over 21+ million strings, do what you want.
 
It really comes down to personal taste and how much one cares about code readability versus speed.
 
For StringBuilder objects of more than just a few thousand…don’t even bother. Convert them to a string, do what you got to do, then convert them back if you really need a StringBuilder.
 

The Code: