Wednesday, January 11, 2012

How to convert List<string> into solid string

I few days ago I've stuck with  really trivial  things. I have to convert List to solid string with delimiter in my high-performance application. I've decided to write some test for this purpose.  

What I'll test:

  • Aggregate Linq extension method.
  • StringBuilder and loop class.
  • string.Concat - yeah, It's not my best code, especially  if I use Concat method in wrong way =)
  • String.Join static method.


Let's do that:

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
class Program
    {
        static void Main(string[] args)
        {
            //generate some data for our test
            var tstList = Enumerable.Range(1, 10000).Select(i => i.ToString()).ToList();
            string delimeter = ",";

            #region List<string> to solid string using Linq extension method
            Stopwatch sw = Stopwatch.StartNew();//start measure time
            string result1 = tstList.Aggregate((i, j) => i + delimeter + j);//run string cancatination using Linq extension
            sw.Stop(); //stop measuring

            Console.WriteLine("linq aggregate func took\t {0}", sw.Elapsed.ToString()); //show result on screen
            #endregion

            #region  List<string> to solid string using StringBuilder class            
            StringBuilder sb = new StringBuilder();
            bool isEmpty = true;
            sw = Stopwatch.StartNew();//start measure time
            for (int i = 0; i < tstList.Count(); i++)
            {//yeah some mess here, I know =)
                if (!isEmpty)
                    sb.Append(",");
                sb.Append(tstList[i]);
                isEmpty = false;
            }            
            sw.Stop(); //stop measuring
            Console.WriteLine("for loop and StringBuilder took\t {0}", sw.Elapsed.ToString());
            #endregion

            
            
            string result3 = string.Empty;
            isEmpty = true;
            sw = Stopwatch.StartNew();//start measure time
            for (int i = 0; i < tstList.Count(); i++)
            {
                if (!isEmpty)
                    result3 = string.Concat(result3, ",");

                result3 = string.Concat(result3, tstList[i]);
                isEmpty = false;
            }
            sw.Stop(); //stop measuring
            Console.WriteLine("string.Concat took\t\t {0}", sw.Elapsed.ToString());


            #region  List<string> to solid string using String.Join
            string result4 = string.Empty;
            sw = Stopwatch.StartNew();//start measure time
            result4 = String.Join(delimeter, tstList.ToArray());
            sw.Stop();
            Console.WriteLine("string.Join took\t\t {0}", sw.Elapsed.ToString());
            #endregion
            //Console.WriteLine(result3); //for test 
            Console.ReadKey();

        }
    }

As result I've got something like that:

I'm really disappointed with Linq Extension Aggregate method. It  takes forever to finish so simple thing.
What  about other methods?
StringBuilder. In every book you will see, that StringBuilder is best for frequently changing strings, because of string class is mutable. Mmmm... I don't know,  I think,  if you have any chance to use string.Concat, do it.
As you can see, string.Concat- is the super fast.
Yeah, I'm definitely will use string.Concat in my  application instead of Linq methods.
and What do you think?
Does Linq  good enough to use in  production environment?

No comments:

Post a Comment