Most efficent way of joining strings

前端 未结 11 1726
佛祖请我去吃肉
佛祖请我去吃肉 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:46

    According to the following test I've made, Join is 3x faster faster on large arrays:

    The Text.txt file contains the value "aaaaaaaaaaaaaaaaaaa" on 38400 lines:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    using System.Diagnostics;
    
    namespace ConsoleApplication1
    {
      class Program
      {
        static void Main(string[] args)
        {
          var strings = File.ReadAllLines("Text.txt");
    
          Stopwatch sw;
    
          StringBuilder sb = new StringBuilder();
    
          sw = Stopwatch.StartNew();
          for (int i = 0; i < strings.Length; i++)
          {
            sb.AppendLine(strings[i]);
          }
          sw.Stop();
          TimeSpan sbTime = sw.Elapsed;
    
          sw = Stopwatch.StartNew();
         var output = string.Join(",", strings);
         sw.Stop();
    
         TimeSpan joinTime = sw.Elapsed;   
    
        }
      }
    }
    

    Output:

    00:00:00.0098754
    00:00:00.0032922
    
    0 讨论(0)
  • 2021-01-18 06:48

    This adhoc implementation I tried with the StrignBuilder is faster than String.Join. More than that String.Join is a MEMORY HOG. I tried with 20000000 strings and String.Join always gives OutOfMemory, when my implementation finishes. On your machine It may be even on less strings if you have less than 8Gb of memory. Comment one of the implementations to test. This holds true unless you use a fixed string[] array. String.Join is good there.

       public static void Main(string[] Args)
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
    
              List<string> strings = new List<string>() {};
            for (double d = 0; d < 8000000; d++) {
                strings.Add(d.ToString());
            }
    
            TimeSpan upTime;
            TimeSpan newupTime;
            using (var pc = new PerformanceCounter("System", "System Up Time"))
            {
                StringBuilder sb = new StringBuilder(strings.Count);
                int i;
    
                pc.NextValue();    //The first call returns 0, so call this twice
                upTime = TimeSpan.FromSeconds(pc.NextValue());
    
                for (i = 0; i < strings.Count - 1; i++)
                {
                    sb.Append(strings[i]);
                    sb.Append(",");
                }
                sb.Append(strings[i]);
    
                newupTime = TimeSpan.FromSeconds(pc.NextValue());
                sb = null;
                Console.WriteLine("SB " + (newupTime - upTime).TotalMilliseconds);
            }
    
            using (var pc = new PerformanceCounter("System", "System Up Time"))
            {
    
                pc.NextValue();
                upTime = TimeSpan.FromSeconds(pc.NextValue());
    
                string s = string.Join(",", strings);
    
                newupTime = TimeSpan.FromSeconds(pc.NextValue());
                Console.WriteLine("JOIN " + (newupTime - upTime).TotalMilliseconds);
            }
    
    
        }
    SB 406
    JOIN 484
    
    0 讨论(0)
  • 2021-01-18 06:49

    StringBuilder is a very efficient way and would be recommended here.

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

    If one wants to be cool and run on Heavy Fuel use Aggregate

    List<string> stringList = new List<string> { "1234567890", "34343434", "4343434" };
    
    Console.WriteLine( stringList.Aggregate( ( current, next ) => string.Format( "{0}, {1}", current, next ) ) );
    
    // Outputs:   1234567890, 34343434, 4343434
    
    0 讨论(0)
  • 2021-01-18 06:51

    As @Ekkehard said, use the string.Join.

    However, you do not need the ToArray() because string.Join has an overload for IEnumerable<string>.

    List<string> stringList = new List<string> 
        { "1234567890", "34343434", "4343434" }; 
    
    string outcome = string.Join(",", stringList);
    

    EDIT

    As @Kobi said, this will work only C# 4.0. In 3.5 I would do.

    var s = new StringBuilder(stringList.Count * 8);
    foreach (var item in stringList)
    {
       s.Append(item);
       s.Append(',');
    }
    s.Length -= 1;
    string outcome = stringList.ToList();
    
    0 讨论(0)
提交回复
热议问题