· Manikandan · problem solving  · 2 min read

String vs StringBuilder vs Span

Problem statement

During a recent interview, I was presented with a problem statement involving the use of the ’#’ symbol. The interviewer explained that this symbol should function as a backspace, and they requested me to devise a logical solution for resolving this scenario

Code

    1:   INPUT ==>      abc#def#            OUTPUT==>  abcdef  
    2:   INPUT ==>      abc##def##          OUTPUT==>  ad      

Solutions 1:

first Solution I write this,

  public string RemoveLastCharWithString(String word)
    {
        string result = "";
        for (int i = 0; i < word.Length; i++)
        {
            if (word[i] != ' ' && word[i] == '#')
            {
                result = result.Remove(result.Length - 1, 1);
            }
            else if (word[i] != '#')
            {
                result += word[i];
            }
        }
        return result;
    }

Solution 2:

I forced to be changed as stringbuilder

 public string RemoveLastCharWithStringBuilder(string word )
    {
        StringBuilder result = new StringBuilder();

        for (int i = 0; i < word.Length; i++)
        {
            if (word[i] != ' ' && word[i] == '#')
            { 
                if (result.Length > 0)
                {
                    result.Remove(result.Length - 1, 1);
                }
            }
            else if (word[i] != '#')
            {
                result.Append(word[i]);
            }
        }
        return result.ToString();
    }

Solution 3:

Then I realised we have other option and its optimized way to do .

   public string RemoveLastCharWithSpan(String word)
    {
        Span<char> buffer = stackalloc char[word.Length];
        int position = 0;

        foreach (char c in word)
        {
            if (c == '#' && position > 0)
            {
                position--;  
            }
            else if (c != '#')
            {
                buffer[position++] = c;  
            }
        }

        return new string(buffer.Slice(0, position));
    }

Benchmark Results

The metrix in below shows the results of our performance benchmarks.

| Method                          | Mean     | Error    | StdDev   | Min      | Max      | Gen0   | Allocated |
|-------------------------------- |---------:|---------:|---------:|---------:|---------:|-------:|----------:|
| RemoveLastCharWithString        | 53.36 ns | 0.873 ns | 1.104 ns | 52.04 ns | 56.01 ns | 0.0497 |     416 B |
| RemoveLastCharWithStringBuilder | 22.77 ns | 0.251 ns | 0.209 ns | 22.59 ns | 23.34 ns | 0.0172 |     144 B |
| RemoveLastCharWithSpan          | 12.08 ns | 0.271 ns | 0.489 ns | 11.38 ns | 12.98 ns | 0.0048 |      40 B |

Note: I will add separate article to show ” How to add BenchMarck in Dotnet ?”

Back to Blog