Creating and manipulating string objects can be useful when building applications. In the C# programming language, string objects contain text values stored as a sequential read-only collection of character objects. This means string objects are immutable and thus can’t be changed once created. Despite this, we often find ourselves needing to manipulate them. In this article, we are going to analyze some of the fastest ways to remove the last character of a string.

To download the source code for this article, you can visit our GitHub repository.

Without further delay, let’s start!

How to Use ReadOnlySpan<char> to Remove the Last Character of a String

Sometimes, we may need to manipulate strings with performance considerations in mind. That’s where the ReadOnlySpan<T> struct comes in handy, providing memory and type-safe representations of our string object. 

Support Code Maze on Patreon to get rid of ads and get the best discounts on our products!
Become a patron at Patreon!

Here’s an example of how we can achieve our goal using the ReadOnlySpan<char>:

var inputSpan = inputString.AsSpan()[..^1];

return new string(inputSpan);

Traditional string manipulation methods often create new string object instances, which leads to more memory utilization and garbage collection overhead. Our example, however, offers better performance and uses the Span.Slice() method to create a slice from our string’s first character to the second-last character. (Note that here we are exercising the Range operator, which will be lowered to call Slice() as seen here). Finally, we return the string representation of the current Span<T> instance.

It is important to note here that we can greatly improve the overall performance of our application if we can continue to operate using the ReadOnlySpan<char> slice rather than creating a new string from it. This will be the fastest way to remove the last character from the string as the ReadOnlySpan<char> provides a view over the original string data without any additional allocation or copying:

return inputString.AsSpan()[..^1];

Remove the Last Character of a String Using LINQ

Besides using ReadOnlySpan<char>, we can also use LINQ to remove the last character of a string:

return new string(inputString.Take(inputString.Length - 1).ToArray());

Our example uses the Enumerable.Take() method to return a range of elements up to the second-last character of the string. 

Use Substring to Remove the Last Character of a String

Besides using LINQ, we can use the String.Substring() method to remove the last character of a string. The method works by retrieving a part of the string from the current string instance:

return inputString.Substring(0, inputString.Length - 1);

Our example utilizes an overload of the String.Substring() method by passing two integer arguments (the index to start from and length) to extract a substring from the first index to the second-last character of the inputString.

Note here we can also employ the Range operator to create the substring:

return inputString[..^1];

Remove the Last Character Using the Remove Method

As the name implies, the String.Remove() method returns a new string object where characters from the current instance are deleted starting from a specific position to the end:

return inputString.Remove(inputString.Length - 1);

Here, we take the current inputString instance and invoke String.Remove(), passing the position of the second-last character. The operation removes the last character of our inputString and returns a new string instance. 

StringBuilder Technique to Remove the Last Character of a String in C#

Besides using the String.Remove() method, we can use the StringBuilder class to remove the last character of a string in C#. Unlike the string class, StringBuilder provides a mutable sequence of characters, allowing for more flexible and memory-efficient modifications of its contents.

Let’s implement an example to understand how we can leverage the StringBuilder class to accomplish our goal:

var stringBuilder = new StringBuilder(inputString);
--stringBuilder.Length;

return stringBuilder.ToString();

Here, we subtract 1 from the StringBuilder.Length property to remove the last character. Since StringBuilder is mutable, the Length property can be adjusted to shrink our “string”. After our modifications, we invoke the stringBuilder.ToString() method to return the final string representation. 

Performance Analysis

Now that we know some of the common ways we can use to remove the last character of a string in C#, let’s see how they perform:

| Method                           | inputString | Mean       | Rank | Gen0   | Allocated |
|--------------------------------- |------------ |-----------:|-----:|-------:|----------:|
| RemoveLastCharAsSpan             | 2147483647  |  0.4986 ns |    1 |      - |         - |
| RemoveLastCharUsingSubstring     | 2147483647  |  6.7735 ns |    2 | 0.0191 |      40 B |
| RemoveLastCharUsingRemove        | 2147483647  |  7.3014 ns |    3 | 0.0191 |      40 B |
| RemoveLastCharUsingSpan          | 2147483647  |  9.9653 ns |    4 | 0.0191 |      40 B |
| RemoveLastCharUsingStringBuilder | 2147483647  | 24.5238 ns |    5 | 0.0688 |     144 B |
| RemoveLastCharUsingLinq          | 2147483647  | 95.2956 ns |    6 | 0.1377 |     288 B |

As we mentioned earlier and now see from the benchmark, converting our string to a ReadOnlySpan<char> and then continuing to use the span without converting to a new string, is the most performant option. It requires no allocation and is lightning-fast. 

If we need to continue our work using a new string object, then we see the next best option is string.Substring(). string.Remove() also performs well, coming in at a close second. Besides that, we can see that using the ReadOnlySpan<T> struct has some performance benefits over the LINQ and StringBuilder techniques. 

Conclusion 

In this article, we learned different ways to remove the last character of a string in C#. However, some offer a clear performance edge, as highlighted in the benchmarks. Which technique have you used before and why? Let us know in the comments section below.

Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!