Most efficent way of joining strings

前端 未结 11 1725
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-18 05:51

I need to concatenate a lot of strings alltogether and put a comma between any of them. I have a list of strings

\"123123123213\"
\"1232113213213\"
\"1232131         


        
相关标签:
11条回答
  • 2021-01-18 06:27

    You should use string.Join() because:

    a) it's much more readable, maintainable and easy on the eyes.

    b) it uses a StringBuilder internally already, so it's very efficient ( you can confirm yourself using Reflector).

    Edit:

    string.Join() uses a StringBuilder for the general case of an IEnumerable<T> input. If you already have an array on the other hand it uses some voodoo magic (including FastAllocateString() and UnSafeCharBuffer) to be even faster.

    0 讨论(0)
  • 2021-01-18 06:27

    There's a benchmark on this page that seems to show that string.Join performs better than StringBuilder on a small array in a lot of iterations. you should probably benchmark for larger arrays also. As I'm posting this I see that BrokenGlass answered that StringBuilder is used internally in string.Join so you can expect it to be faster I guess.

    0 讨论(0)
  • 2021-01-18 06:30

    Your second solution adds an extra , at the end. Take a look at Eric Lippert`s blog entry

    I would recommend fixing your second solution. A StringBuilder would be definitely faster, as you avoid coping the list contents to a new array.

    StringBuilder builder = new StringBuilder();
    string separator = "";
    stringList.ForEach(
        val =>
        {
            builder.Append(separator).Append(val);
            separator = ",";
        });
    string outcome = builder.ToString();
    
    0 讨论(0)
  • 2021-01-18 06:31

    Use Join, because it doesn't add a trailing ",".

    0 讨论(0)
  • 2021-01-18 06:34

    String.Join is the fastest if you have a fixed number of strings to join. The deeper reason is that String.Join does loop over the array and allocates the final string buffer with the right size because it does in the first pass add the string length of all strings together. You can get similar results when you play around with StringBuilder and its capacity. The golden rule is to spare memory allocations at the cost of looping over the array two times. Which approach is faster depends on how many items you have in your list and how big the resultint string will get.

    Yours, Alois Kraus

    0 讨论(0)
  • 2021-01-18 06:44

    Test code:

    public static void Performance(Action fn)
    {
        var timer = new Stopwatch();
        timer.Start();
    
        for (var i = 0; i < 10000000; ++i)
        {
            fn();
        }
    
        timer.Stop();
    
        Console.WriteLine("{0} Time: {1}ms ({2})", fn.ToString(), timer.ElapsedMilliseconds, timer.ElapsedTicks);
    }
    
    static void Main(string[] args)
    {
        var stringList = new List<string>() {
            "123123123213",
            "1232113213213",
            "123213123"
        };
    
        string outcome = String.Empty;
        Performance(() =>
        {
            outcome = string.Join(",", stringList);
        });
    
        Console.WriteLine(outcome);
    
        Performance(() =>
        {
            StringBuilder builder = new StringBuilder();
            stringList.ForEach
                (
                    val =>
                    {
                        builder.Append(val);
                        builder.Append(",");
                    }
                );
            outcome = builder.ToString();
            outcome = outcome.Substring(0, outcome.Length - 1);
        });
    
        Console.WriteLine(outcome);
    
        Console.ReadKey();
    
    }
    

    Result 1. String.Join - 2. StringBuilder + SubString. ####ms (ticks)

    result

    In this case String.Join is faster, but if you are ok with a trailing , then

    string builder

    StringBuilder is slightly faster (with a trailing ,).

    0 讨论(0)
提交回复
热议问题