In this article, we will perform benchmark tests to determine the fastest way to get the first N characters of a string in C#. We will start by creating an input string. Then, we will define and explain different methods that we can utilize to accomplish this task. At the end, we will use the BenchmarkDotNet library to compare and rank the performances of these methods.
Alright, let’s dive in.
Setup the Environment
Before we explore our methods, let’s define our input string and the number of characters we want to retrieve:
public class FirstNCharactersOfStringGetter(string inputString = "CodeMaze", int numberOfCharacters = 4) { }
In this primary constructor, we define our input string and the number of characters we want to obtain from it as optional parameters. We set the default value of our string to "CodeMaze"
and specify that the default number of characters we wish to retrieve as 4
.
Now, for most of the methods that we will implement, attempting to retrieve more characters from a string than it contains will result in exceptions. Therefore, to avoid these exceptions, let’s define a method to check for this scenario:
private bool IsInputStringShorter() => inputString.Length < numberOfCharacters;
In this method, we check if our string is shorter than the number of characters we intend to retrieve. If it is, this method returns true.
Different Methods to Get the First N Characters of a String
Now, with our setup complete, let’s implement seven methods to get the first N characters of a string. To improve their performance, most of our methods will use a ReadOnlySpan<char>
as their return type. Therefore, when we return strings or arrays from these methods, they are implicitly converted to a ReadOnlySpan<char>
. For an in-depth look at Span<T>
and ReadOnlySpan<T>
be sure to check out our article How to Use Span in C# to Improve Application Performance.
Let’s now create and discuss some different methods to get the first N characters of a string.
Get the First N Characters of a String Using a for Loop
First, let’s use a for
loop to retrieve the first N characters of our string:
public ReadOnlySpan<char> UseForLoop() { if (IsInputStringShorter()) return inputString; var dest = new char[numberOfCharacters]; for (int i = 0; i < numberOfCharacters; i++) { dest[i] = inputString[i]; } return dest; }
Here, we start by checking if the length of our string is less than the number of characters we want to obtain. If it is, we return the string without performing any operation.
However, if the length of our string is sufficient, we use a for
loop to get the first N characters. We start this process by creating a character array that has the number of characters we want to retrieve as its size. Then, in our loop, we iterate over our input string and add its characters to our array until we reach the specified length.
Finally, we return the array.
Utilize the Remove Method
Next up, let’s use the Remove()
method:
public ReadOnlySpan<char> UseRemove() { if (IsInputStringShorter()) return inputString; return inputString.Remove(numberOfCharacters); }
Again, we first check to ensure that our string has enough characters.
If it does, then we invoke the Remove()
method on the string. This method returns a new string that is equivalent to our input string minus all the characters starting from the numberOfCharacters
index until the end of the string.
Use the AsSpan Method to Get the First N Characters of a String
Moving forward, let’s discuss how to utilize the AsSpan()
method to perform this task:
public ReadOnlySpan<char> UseAsSpan() { if (IsInputStringShorter()) return inputString; return inputString.AsSpan(0, numberOfCharacters); }
Once again, we invoke our IsInputStringShorter()
method to check if our string has enough characters.
If the string meets this criteria, we use the AsSpan()
method to create a new ReadOnlySpan<char>
object from a portion of our string. The two arguments we provide to the AsSpan()
method, denote the index where our ReadOnlySpan
slice should start and its length.
For example, if we use the default value of our numberOfCharacters
parameter, which is 4
, the AsSpan()
method will create a ReadOnlySpan
that contains the first four characters of our string.
Get the First N Characters of a String Using the AsSpan Method with a Range Operator
Now, let’s use the AsSpan()
method differently.
Let’s see how we can convert our entire string to a ReadOnlySpan<char>
and then extract the characters we want:
public ReadOnlySpan<char> UseAsSpanWithRangeOperator() => IsInputStringShorter() ? inputString : inputString.AsSpan()[..numberOfCharacters];
This time, we use the ternary operator instead of an if-else statement. We begin by checking if our string is shorter than the desired number of characters. If it is, we return the original string.
Otherwise, we call the AsSpan()
method to cast our string to a ReadOnlySpan<char>
and utilize the range operator to get the characters we want. Specifically, we use the [..numberOfCharacters]
operator to extract characters from the beginning of our ReadOnlySpan
up to the character at the index numberOfCharacters - 1
.
Get the First N Characters of a String With LINQ
Next, let’s use a LINQ method to carry out this task:
public IEnumerable<char> UseLINQEnumerable() => inputString.Take(numberOfCharacters);
Here, we invoke the Take()
method to get an IEnumerable<char>
that contains our desired characters.
Note that we do not perform our length check in this method, because the Take()
method will return our input string if the number of characters we want exceeds the length of the string.
Use the ToCharArray Method
Now, let’s talk about the ToCharArray()
method:
public ReadOnlySpan<char> UseToCharArray() { if (IsInputStringShorter()) return inputString; return inputString.ToCharArray(0, numberOfCharacters); }
For this approach, once again we begin by calling our IsInputStringShorter()
method. If it returns true, we return the input string.
Otherwise, we pass two arguments to the ToCharArray()
method and call it on our string. This method copies the number of characters we specify from our string into a new char array. In our case, we want all the characters from the beginning of the string to the index numberOfCharacters - 1
.
After that, we return the array.
Benchmarking Our Methods
Now that we have implemented all our methods, let’s compare their performance.
We use the BenchmarkDotnet
library for this comparison. For more information on this library, please visit our Introduction to Benchmarking C# Projects.
Of course, we already prepared the benchmark and you can find it in our source code linked in this article.
Now, let’s check the results:
| Method | Mean | Error | StdDev | Gen0 | Allocated | |--------------------------- |-----------:|----------:|----------:|-------:|----------:| | UseAsSpan | 0.3489 ns | 0.0108 ns | 0.0101 ns | - | - | | UseAsSpanWithRangeOperator | 0.4178 ns | 0.0135 ns | 0.0126 ns | - | - | | UseToCharArray | 7.9897 ns | 0.1138 ns | 0.1008 ns | 0.0102 | 32 B | | UseRemove | 8.2838 ns | 0.0814 ns | 0.0680 ns | 0.0102 | 32 B | | UseForLoop | 8.5426 ns | 0.0804 ns | 0.1073 ns | 0.0102 | 32 B | | UseLINQEnumerable | 37.2699 ns | 0.2369 ns | 0.1979 ns | 0.0280 | 88 B |
As we can see from these results, using the AsSpan()
method to create a ReadOnlySpan
that contains only our desired characters is the fastest way to get the first N Characters of a string in C#.
In the second place, we see the AsSpan()
method that involves converting our entire string into a ReadOnlySpan
and retrieving the characters we want from that span.
From the results, it’s also evident that the top two methods are the methods that create a span from our string. In addition to their fast execution speed, these methods do not allocate any memory. We also do not perform any garbage collection during their operation.
After these methods, we have the UseToCharArray()
, UseForLoop()
, and UseRemove()
methods. These methods allocate managed memory, which leads to garbage collection.
Finally, the slowest way to get the first N characters of a string is by using LINQ. Even though we avoid the initial length check in this method, it displays the longest execution time.
Conclusion
In this article, we have determined the fastest way to get the First N characters of a string.
First, we implemented and discussed six different methods to perform this task. Then, we compared the performances of these methods using the BenchmarkDotnet library.
From the benchmark results, we concluded that using AsSpan() to get a ReadOnlySpan of our desired characters is the fastest way to get the first N characters of a string in C#.