StringBuilder much much faster and better than String forconcatenation !!!

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • raylopez99

    StringBuilder much much faster and better than String forconcatenation !!!

    StringBuilder better and faster than string for adding many strings.

    Look at the below. It's amazing how much faster StringBuilder is than
    string.

    The last loop below is telling: for adding 200000 strings of 8 char
    each, string took over 25 minutes while StringBuilder took 40
    milliseconds!

    Can anybody explain such a radical difference?

    The hardware running this program was a Pentium IV with 2 GB RAM.

    RL

    // stringbuilder much faster than string in concatenation

    //////////////
    using System;
    using System.Collecti ons.Generic;
    using System.Linq;
    using System.Text;

    namespace console1
    {
    class Program
    {
    static void Main(string[] args)
    {
    Console.WriteLi ne("hi \n");
    UpdateTime myUpdateTime = new UpdateTime(1000 );
    myUpdateTime.Up dateTimeMethod( );
    Console.WriteLi ne("times str,sb are: {0}, {1}",
    myUpdateTime.tx tConcatTime, myUpdateTime.tx tStringBTime);
    }
    }
    }

    /*
    * OUTPUT
    * results:
    * for 1000 iterations: string = 10.01ms; stringbuilder = 0
    * for 5000 iterations: string = 410.6ms; stringbuilder = 0
    * for 50k iterations: sring = 79013 ms; stringbuilder = 0;
    * for 10k iterations : string = 1772.5 ms; stringbuilder = 0;
    * for 75k iterations : string = 186237.8ms; stringbuilder = 20.03
    ms
    * for 100k iterations : string = 334.4k ms (5.6 min); stringbuilder =
    20.03 ms;
    * for 200k iterations: string = 1515.6k ms (25.3 min); stringbuilder
    = 40.06 ms;
    *
    *
    * */
    //////////////////////////////
    using System;
    using System.Collecti ons.Generic;
    using System.Linq;
    using System.Text;

    namespace console1
    {
    class UpdateTime
    {
    int txtInterations;
    public string txtConcatTime;
    public string txtStringBTime;
    public UpdateTime(int i)
    {
    txtInterations = i;
    txtConcatTime = "";
    txtStringBTime = "";
    }

    public void UpdateTimeMetho d()
    {

    int iterations = txtInterations;

    string theString = "MyString";

    DateTime strCall = DateTime.Now;

    string targetString = null;

    for (int x = 0; x < iterations; x++)
    {
    targetString += theString;
    }

    TimeSpan time = (DateTime.Now - strCall);

    txtConcatTime = time.TotalMilli seconds.ToStrin g();

    //StringBuilder

    DateTime inCall = DateTime.Now;

    string theString2 = "MyStrig2";
    StringBuilder sb = new StringBuilder(t heString2);

    for (int x = 0; x < iterations; x++)
    {
    sb.Append(theSt ring2);
    }

    time = (DateTime.Now - inCall);

    txtStringBTime = time.TotalMilli seconds.ToStrin g();



    }

    }
    }
    /////////////////////
  • colin

    #2
    Re: StringBuilder much much faster and better than String for concatenation !!!

    ive noticed this, and have had to use it in verious places,
    usualy after ive run profiler, to see where its needed.

    basically theres a fair bit of work when you add two strings together,
    as your making a new object each time, stringbuilder is a single object,
    and so doesnt have any where near the same overhead to apend.

    Colin.

    "raylopez99 " <raylopez99@yah oo.comwrote in message
    news:46bd32b3-d6c8-429b-95d1-a8987610969f@m4 5g2000hsb.googl egroups.com...
    StringBuilder better and faster than string for adding many strings.
    >
    Look at the below. It's amazing how much faster StringBuilder is than
    string.
    >
    The last loop below is telling: for adding 200000 strings of 8 char
    each, string took over 25 minutes while StringBuilder took 40
    milliseconds!
    >
    Can anybody explain such a radical difference?
    >
    The hardware running this program was a Pentium IV with 2 GB RAM.
    >
    RL

    Comment

    • Brian Gideon

      #3
      Re: StringBuilder much much faster and better than String forconcatenatio n !!!

      On Sep 22, 8:36 am, raylopez99 <raylope...@yah oo.comwrote:
      StringBuilder better and faster than string for adding many strings.
      >
      Look at the below.  It's amazing how much faster StringBuilder is than
      string.
      >
      The last loop below is telling:  for adding 200000 strings of 8 char
      each, string took over 25 minutes while StringBuilder took 40
      milliseconds!
      >
      Can anybody explain such a radical difference?
      >
      The hardware running this program was a Pentium IV with 2 GB RAM.
      >
      RL
      See the following article.



      Comment

      • Jon Skeet [C# MVP]

        #4
        Re: StringBuilder much much faster and better than String for concatenation !!!

        raylopez99 <raylopez99@yah oo.comwrote:
        StringBuilder better and faster than string for adding many strings.
        >
        Look at the below. It's amazing how much faster StringBuilder is than
        string.
        >
        The last loop below is telling: for adding 200000 strings of 8 char
        each, string took over 25 minutes while StringBuilder took 40
        milliseconds!
        >
        Can anybody explain such a radical difference?
        Very easily. It's all to do with creating copies. This difference is
        the whole point of StringBuilder existing in the first place.

        See http://pobox.com/~skeet/csharp/stringbuilder.html

        --
        Jon Skeet - <skeet@pobox.co m>
        Web site: http://www.pobox.com/~skeet
        Blog: http://www.msmvps.com/jon.skeet
        C# in Depth: http://csharpindepth.com

        Comment

        • Marc Gravell

          #5
          Re: StringBuilder much much faster and better than String forconcatenatio n !!!

          The "string table" you mention is the interner; by default, strings in
          compiled code get interned, but not strings that you build at runtime
          (for example, via concatenation); as such, the string "abc" never gets
          collected, because it is interned. In fact, the compiler is too clever
          by half, and actually does the "abcd" concatenation itself, so the
          string "abcd" is interned too ;-p

          StringBuilder *operates* like a list/array of characters, but is
          actually implemented as a regular .NET string, which it abuses and
          tortures to mutate at runtime.

          Marc

          Comment

          • Duggi

            #6
            Re: StringBuilder much much faster and better than String forconcatenatio n !!!

            On Sep 22, 7:15 am, Jon Skeet [C# MVP] <sk...@pobox.co mwrote:
            raylopez99 <raylope...@yah oo.comwrote:
            StringBuilder better and faster than string for adding many strings.
            >
            Look at the below.  It's amazing how much faster StringBuilder is than
            string.
            >
            The last loop below is telling:  for adding 200000 strings of 8 char
            each, string took over 25 minutes while StringBuilder took 40
            milliseconds!
            >
            Can anybody explain such a radical difference?
            >
            Very easily. It's all to do with creating copies. This difference is
            the whole point of StringBuilder existing in the first place.
            >
            Seehttp://pobox.com/~skeet/csharp/stringbuilder.h tml
            >
            --
            Jon Skeet - <sk...@pobox.co m>
            Web site:http://www.pobox.com/~skeet 
            Blog:http://www.msmvps.com/jon.skeet
            C# in Depth:http://csharpindepth.com
            See http://pobox.com/~skeet/csharp/stringbuilder.html that was a good
            article...

            Thanks Jon.

            -Cnu

            Comment

            • =?ISO-8859-1?Q?G=F6ran_Andersson?=

              #7
              Re: StringBuilder much much faster and better than String forconcatenatio n !!!

              raylopez99 wrote:
              The last loop below is telling: for adding 200000 strings of 8 char
              each, string took over 25 minutes while StringBuilder took 40
              milliseconds!
              >
              Can anybody explain such a radical difference?
              For each time you add eight characters to the string, the entire string
              is copied into a new string along with the new characters.

              In the first iteration you copy 16 bytes (8 character, each two bytes).
              In the second iteration you copy 32 bytes.
              In the third iteration you copy 48 bytes.
              And son on...

              When you reach the 200000th iteration, you will have copied:

              16*(1+2+3+4+5+. ..+200000) = 16*(100000*2000 01) = 320001600000 bytes

              That is 320 GB. That 160 times more than you have in your computer. To
              create a string that is 1600000 characters, you have copied 100000 times
              that much data.

              The StringBuilder has to grow it's internal string several times during
              the loop, but each time it's size is doubled, so in the end the
              StringBuilder will have copied about two times the size of the string.

              So in this case the StringBuilder should be about 50000 times faster
              than concatenating the strings, which corresponds to your result.

              (If you specify the final size when creating the StringBuilder, the
              interal string never has to be reallocated, so it will be twice as fast.)
              int txtInterations;
              If you want to use hungarinan notation to specify the data type, you
              should not use a prefix that contradicts the data type.

              However, in a type safe language there isn't really any need to use
              hungarian notation to keep track of the data types.

              --
              Göran Andersson
              _____
              Göran Anderssons privata hemsida.

              Comment

              • raylopez99

                #8
                Re: StringBuilder much much faster and better than String forconcatenatio n !!!

                Göran Andersson wrote:
                When you reach the 200000th iteration, you will have copied:
                >
                16*(1+2+3+4+5+. ..+200000) = 16*(100000*2000 01) = 320001600000 bytes
                >
                That is 320 GB. That 160 times more than you have in your computer. To
                create a string that is 1600000 characters, you have copied 100000 times
                Well that's interesting Goran. But my PC did not crash, and I don't
                have 320 GB of HD, so somehow it must be doing some fancy stuff in the
                background to truncate.

                The StringBuilder has to grow it's internal string several times during
                the loop, but each time it's size is doubled, so in the end the
                StringBuilder will have copied about two times the size of the string.
                >
                So in this case the StringBuilder should be about 50000 times faster
                than concatenating the strings, which corresponds to your result.
                >
                (If you specify the final size when creating the StringBuilder, the
                interal string never has to be reallocated, so it will be twice as fast.)
                That's counterintuitiv e, if you're saying specifiying the final size
                will make StringBuilder *slower*. Very strange if true. Anyway I
                never specify anything so I'm OK.
                >
                int txtInterations;
                >
                If you want to use hungarinan notation to specify the data type, you
                should not use a prefix that contradicts the data type.
                >
                However, in a type safe language there isn't really any need to use
                hungarian notation to keep track of the data types.
                And why is that? Anyhow, I just discovered this cool property for
                runtime type checking:

                // using public static object ChangeType (object value, Type
                conversionType) ;
                // example:

                Type myTargetType = typeof (int);
                object theSourceStr = “42”;
                object theResult = Convert.ChangeT ype(theSourceSt r, myTargetType);
                Console.WriteLi ne(theResult); //42
                Console.WriteLi ne(theResult.Ge tType()); //System.Int32

                //pretty cool, eh? I bet it only works though for 'primitive' data
                types like int, etc.
                // UPDATE: I see C# has no easy way of casting any object...or so it
                seems. I'll post in a separate thread on this...

                RL

                Comment

                • gerry

                  #9
                  Re: StringBuilder much much faster and better than String for concatenation !!!

                  assuming all the calcs here are correct,
                  your computer shouldn't crash, you have COPIED 320GB of data, however the
                  largest string actually created is only 1.6GB.
                  after a string has been copied it is available for garbage collection and
                  part of the vast time difference you are seeing is GC doing its job.

                  re specifiying the final size being 'twice as fast' , that would be twice
                  as fast as not specifying a final size -or- 100000 times faster that
                  concatenating strings


                  "raylopez99 " <raylopez99@yah oo.comwrote in message
                  news:ed6db8b7-a05a-45d0-b80e-b7166298bbf1@c5 8g2000hsc.googl egroups.com...
                  Göran Andersson wrote:
                  When you reach the 200000th iteration, you will have copied:
                  >
                  16*(1+2+3+4+5+. ..+200000) = 16*(100000*2000 01) = 320 001 600 000 bytes
                  >
                  That is 320 GB. That 160 times more than you have in your computer. To
                  create a string that is 1 600 000 characters, you have copied 100000 times
                  Well that's interesting Goran. But my PC did not crash, and I don't
                  have 320 GB of HD, so somehow it must be doing some fancy stuff in the
                  background to truncate.

                  The StringBuilder has to grow it's internal string several times during
                  the loop, but each time it's size is doubled, so in the end the
                  StringBuilder will have copied about two times the size of the string.
                  >
                  So in this case the StringBuilder should be about 50000 times faster
                  than concatenating the strings, which corresponds to your result.
                  >
                  (If you specify the final size when creating the StringBuilder, the
                  interal string never has to be reallocated, so it will be twice as fast.)
                  That's counterintuitiv e, if you're saying specifiying the final size
                  will make StringBuilder *slower*. Very strange if true. Anyway I
                  never specify anything so I'm OK.
                  >
                  int txtInterations;
                  >
                  If you want to use hungarinan notation to specify the data type, you
                  should not use a prefix that contradicts the data type.
                  >
                  However, in a type safe language there isn't really any need to use
                  hungarian notation to keep track of the data types.
                  And why is that? Anyhow, I just discovered this cool property for
                  runtime type checking:

                  // using public static object ChangeType (object value, Type
                  conversionType) ;
                  // example:

                  Type myTargetType = typeof (int);
                  object theSourceStr = “42”;
                  object theResult = Convert.ChangeT ype(theSourceSt r, myTargetType);
                  Console.WriteLi ne(theResult); //42
                  Console.WriteLi ne(theResult.Ge tType()); //System.Int32

                  //pretty cool, eh? I bet it only works though for 'primitive' data
                  types like int, etc.
                  // UPDATE: I see C# has no easy way of casting any object...or so it
                  seems. I'll post in a separate thread on this...

                  RL


                  Comment

                  • Brian Gideon

                    #10
                    Re: StringBuilder much much faster and better than String forconcatenatio n !!!

                    On Sep 22, 2:43 pm, raylopez99 <raylope...@yah oo.comwrote:
                    Göran Andersson wrote:
                    When you reach the 200000th iteration, you will have copied:
                    >
                    16*(1+2+3+4+5+. ..+200000) = 16*(100000*2000 01) = 320001600000 bytes
                    >
                    That is 320 GB. That 160 times more than you have in your computer. To
                    create a string that is 1600000 characters, you have copied 100000 times
                    >
                    Well that's interesting Goran.  But my PC did not crash, and I don't
                    have 320 GB of HD, so somehow it must be doing some fancy stuff in the
                    background to truncate.
                    All of that memory isn't in play simultaneously.
                    >
                    The StringBuilder has to grow it's internal string several times during
                    the loop, but each time it's size is doubled, so in the end the
                    StringBuilder will have copied about two times the size of the string.
                    >
                    So in this case the StringBuilder should be about 50000 times faster
                    than concatenating the strings, which corresponds to your result.
                    >
                    (If you specify the final size when creating the StringBuilder, the
                    interal string never has to be reallocated, so it will be twice as fast..)
                    >
                    That's counterintuitiv e, if you're saying specifiying the final size
                    will make StringBuilder *slower*.  Very strange if true.  Anyway I
                    never specify anything so I'm OK.
                    >
                    He said it would be twice as *fast*.
                    >
                    >
                            int txtInterations;
                    >
                    If you want to use hungarinan notation to specify the data type, you
                    should not use a prefix that contradicts the data type.
                    >
                    However, in a type safe language there isn't really any need to use
                    hungarian notation to keep track of the data types.
                    >
                    And why is that?  
                    I'll pass on that.
                    Anyhow, I just discovered this cool property for
                    runtime type checking:
                    >
                    // using public static object ChangeType (object value, Type
                    conversionType) ;
                    // example:
                    >
                    Type myTargetType = typeof (int);
                      object theSourceStr = “42”;
                      object theResult = Convert.ChangeT ype(theSourceSt r, myTargetType);
                      Console.WriteLi ne(theResult); //42
                      Console.WriteLi ne(theResult.Ge tType()); //System.Int32
                    >
                    //pretty cool, eh?  I bet it only works though for 'primitive' data
                    types like int, etc.
                    // UPDATE:  I see C# has no easy way of casting any object...or so it
                    seems.  I'll post in a separate thread on this...
                    >
                    It does, but like you said it's better to post that question in
                    another thread.

                    Comment

                    • raylopez99

                      #11
                      Re: StringBuilder much much faster and better than String forconcatenatio n !!!

                      Brian Gideon wrote:

                      OK, got it. And I understood now Hungarian Notation not needed since
                      the compiler will catch your error.

                      RL

                      Comment

                      • Brian Gideon

                        #12
                        Re: StringBuilder much much faster and better than String forconcatenatio n !!!

                        On Sep 22, 3:37 pm, raylopez99 <raylope...@yah oo.comwrote:
                        Brian Gideon wrote:
                        >
                        OK, got it.  And I understood now Hungarian Notation not needed since
                        the compiler will catch your error.
                        >
                        RL
                        Basically. And for what it's worth I've adopted the "m_" prefix for
                        instance members and "s_" for static members.

                        Comment

                        • Peter Duniho

                          #13
                          Re: StringBuilder much much faster and better than String forconcatenatio n !!!

                          On Mon, 22 Sep 2008 09:58:48 -0700, Göran Andersson <guffa@guffa.co m>
                          wrote:
                          [...]
                          > int txtInterations;
                          >
                          If you want to use hungarinan notation to specify the data type, you
                          should not use a prefix that contradicts the data type.
                          I hope that's a statement that anyone can perceive as trivially true. :)
                          However, in a type safe language there isn't really any need to use
                          hungarian notation to keep track of the data types.
                          I will insert my standard disclaimer here:

                          Even in a type unsafe language, Hungarian's primary purpose isn't to keep
                          track of the data type. If and when the type is identical to the semantic
                          of the variable, then of course it will. But otherwise, the type tag (not
                          prefix) in Hungarian reflects the _semantic_ usage of the data, not it's
                          literal type.

                          In fact, for variables that are typed as built-in types such as "int",
                          "char", etc. the tag will most often _not_ reflect the actual type of the
                          variable. For example, "x", "dx", and "cx" are common variable names when
                          dealing with the X coordinate in a Cartesian coordinate space, but they
                          can all refer to a variety of integral types: "int", "short", "ushort",
                          "long", etc. In the Hungarian philosophy, the naming is there to ensure
                          semantic correctness, not compiler correctness.

                          This is in fact why Hungarian is still valuable even when using a
                          strongly-typed language.

                          This is something that Microsoft's "Systems" version of Hungarian gets
                          very, very wrong. Unfortunately, that's the Hungarian most people are
                          exposed to.

                          Pete

                          Comment

                          • =?UTF-8?B?R8O2cmFuIEFuZGVyc3Nvbg==?=

                            #14
                            Re: StringBuilder much much faster and better than String for concatenation!! !

                            Peter Duniho wrote:
                            Even in a type unsafe language, Hungarian's primary purpose isn't to
                            keep track of the data type. If and when the type is identical to the
                            semantic of the variable, then of course it will. But otherwise, the
                            type tag (not prefix) in Hungarian reflects the _semantic_ usage of the
                            data, not it's literal type.
                            >
                            In fact, for variables that are typed as built-in types such as "int",
                            "char", etc. the tag will most often _not_ reflect the actual type of
                            the variable. For example, "x", "dx", and "cx" are common variable
                            names when dealing with the X coordinate in a Cartesian coordinate
                            space, but they can all refer to a variety of integral types: "int",
                            "short", "ushort", "long", etc. In the Hungarian philosophy, the naming
                            is there to ensure semantic correctness, not compiler correctness.
                            >
                            This is in fact why Hungarian is still valuable even when using a
                            strongly-typed language.
                            >
                            This is something that Microsoft's "Systems" version of Hungarian gets
                            very, very wrong. Unfortunately, that's the Hungarian most people are
                            exposed to.
                            >
                            Pete
                            I've done quite a bit ASP/VBScript, and although it wasn't exactly the
                            original intention of the hungarian notation, using it to keep track of
                            the data type is very useful in that environment. Otherwise you could
                            easily get surprised by the results, like:

                            Dim page
                            page = Request.QuerySt ring("page")
                            If page = 42 Then
                            ' we don't get here even if we put 42 in the query string
                            ' as the variable page contains "42", not 42.
                            End If

                            --
                            Göran Andersson
                            _____
                            Göran Anderssons privata hemsida.

                            Comment

                            • =?windows-1252?Q?G=F6ran_Andersson?=

                              #15
                              Re: StringBuilder much much faster and better than String forconcatenatio n !!!

                              raylopez99 wrote:
                              Göran Andersson wrote:
                              >
                              >When you reach the 200000th iteration, you will have copied:
                              >>
                              >16*(1+2+3+4+5+ ...+200000) = 16*(100000*2000 01) = 320001600000 bytes
                              >>
                              >That is 320 GB. That 160 times more than you have in your computer. To
                              >create a string that is 1600000 characters, you have copied 100000 times
                              >
                              Well that's interesting Goran. But my PC did not crash, and I don't
                              have 320 GB of HD, so somehow it must be doing some fancy stuff in the
                              background to truncate.
                              For each string that you create, the previous string is up for garbage
                              collection.

                              As you go through a lot more memory than there are in the computer, it
                              means that it has done more than 160 garbage collections during the
                              loop, and probably something closer to a 1000.
                              >The StringBuilder has to grow it's internal string several times during
                              >the loop, but each time it's size is doubled, so in the end the
                              >StringBuilde r will have copied about two times the size of the string.
                              >>
                              >So in this case the StringBuilder should be about 50000 times faster
                              >than concatenating the strings, which corresponds to your result.
                              >>
                              >(If you specify the final size when creating the StringBuilder, the
                              >interal string never has to be reallocated, so it will be twice as fast.)
                              >
                              That's counterintuitiv e, if you're saying specifiying the final size
                              will make StringBuilder *slower*. Very strange if true. Anyway I
                              never specify anything so I'm OK.
                              If you find it counter intuitive, then perhaps you should read it again
                              to see if you got it right. In this case you got it backwards.
                              Anyhow, I just discovered this cool property for
                              runtime type checking:
                              >
                              // using public static object ChangeType (object value, Type
                              conversionType) ;
                              // example:
                              >
                              Type myTargetType = typeof (int);
                              object theSourceStr = “42”;
                              object theResult = Convert.ChangeT ype(theSourceSt r, myTargetType);
                              Console.WriteLi ne(theResult); //42
                              Console.WriteLi ne(theResult.Ge tType()); //System.Int32
                              >
                              //pretty cool, eh? I bet it only works though for 'primitive' data
                              types like int, etc.
                              The type has to implement the IConvertible interface, which the
                              primitive types do.

                              The primitive types already have methods in the Convert class, so
                              instead of doing Convert.ChangeT ype(var, typeof(int)) you can use
                              Convert.ToInt32 (var).

                              Casting to a type that you specify dynamically isn't very useful in a
                              strongly typed language. You can't do much with the data anyway without
                              casting the reference to the actual type.
                              // UPDATE: I see C# has no easy way of casting any object...or so it
                              seems. I'll post in a separate thread on this...
                              Converting a string to an int is parsing. There are several method for
                              doing that, like int.Parse(strin g), int.TryParse(st ring, out int),
                              Convert.ToInt32 (string)...

                              For casting, C# uses the same syntax as C/C++:

                              int value = 42;
                              long bigValue = (long)value;

                              --
                              Göran Andersson
                              _____
                              Göran Anderssons privata hemsida.

                              Comment

                              Working...