Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

StringBuilder as class member? [closed]

Is it efficient (or necessary?) to make StringBuilder a member of class, and use it in class methods whenever string concatenation is to be done?

Or just use new StringBuidler() before such operations?

I suspect it is efficient if there is a StringBuilder ready for use there.

Xing

like image 238
Chengting Avatar asked Sep 26 '22 23:09

Chengting


1 Answers

It's an interesting question, and one that's been researched.

The answer is, yes, under extreme test conditions it's more efficient to share a single instance and reuse it than it is to create a new StringBuilder each time.

But, no, it's almost never necessary, and probably a bad idea in most cases. Other considerations like thread-safety are generally more important than micro-optimizing prematurely.

The following code from the linked article does a highly artificial performance test:

using System;
using System.Diagnostics;
using System.Text;

class Program
{
    static string Method1()
    {
        StringBuilder builder = new StringBuilder();
        foreach (string value in _array)
            builder.Append(value);
        return builder.ToString();
    }

    static StringBuilder _builder = new StringBuilder();

    static string Method2()
    {
        StringBuilder builder = _builder;
        builder.Clear();
        foreach (string value in _array)
            builder.Append(value);
        return builder.ToString();
    }

    static string[] _array = { "dot", "net", "perls", "string", "array" };
    const int _max = 1000000;
    static void Main()
    {
        Method1();
        Method2();

        // Version 1: use new StringBuilder each time.
        var s1 = Stopwatch.StartNew();
        for (int i = 0; i < _max; i++)
        {
            Method1();
        }
        s1.Stop();

        // Version 2: reuse a single StringBuilder instance.
        var s2 = Stopwatch.StartNew();
        for (int i = 0; i < _max; i++)
        {
            Method2();
        }
        s2.Stop();
        Console.WriteLine(s1.Elapsed.TotalMilliseconds);
        Console.WriteLine(s2.Elapsed.TotalMilliseconds);
        Console.Read();
    }
}

The result (I've just run it myself):

  • Repeated allocation: 146.21
  • StringBuilder as field: 98.96
like image 122
Baldrick Avatar answered Oct 11 '22 15:10

Baldrick