String concatination... which is the best way??

Agent707

Newcomer
Joined
Jul 9, 2004
Messages
19
Location
Knoxville, TN
I have a couple of developers having a "discussion" about which is the more efficient way of doing string concatination... :-\

And when I say efficient, I mean "faster execution" wise.
Visual Basic:
'#1
sVar = "This is some text "
sVar += "and this is some more text "
sVar += "...etc..." & someVar & " some more text"
'....etc. on for a thousand lines...

'#2
sVar = "This is some text " & _
          "and this is some more text " & _
          "...etc..."  & someVar & " some more text"
'And every so many rows, 40 or 50?, add to it like so...
sVar += "and another 40 or 50 so lines of text." & _
Now imaging this type of coding with a thousand lines instead of 3.

I have always used method #2. This one guy has always used #1, though he says he "thinks" #2 is more efficient. The other guy is just a trouble maker and says everyone is wrong and he is right, but he has no opinion. :rolleyes:

Does anyone have any "technical" explanation of which method is the preferred? IF there is any?
 
Technically I would have thought the best way to create the string would be using the StringBuilder class. If I had to choose one of those methods I'd have personally done it using method #2. The string class is immutable, which makes using += a slow method. I cannot however say for sure this doesn't also make using the & equally as inefficient.
 
Just did the following in a simple app
C#:
            string s1 = "Test ";
            s1 += "more test ";
            s1 += "even more test.";

            string s2 = "Test "
                + "more test "
                + "even more test";

and checked the reultant IL and got
Code:
  IL_0001:  ldstr      "Test "
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  ldstr      "more test "
  IL_000d:  call       string [mscorlib]System.String::Concat(string,
                                                              string)
  IL_0012:  stloc.0
  IL_0013:  ldloc.0
  IL_0014:  ldstr      "even more test."
  IL_0019:  call       string [mscorlib]System.String::Concat(string,
                                                              string)
  IL_001e:  stloc.0
  IL_001f:  ldstr      "Test more test even more test"
  IL_0024:  stloc.1

so for doing straight string building the second is a lot quicker as the compiler optimises the entire thing away.

If you are concatenating variables into the string then it will do it's best to optimise as the following C# and IL show -

C#:
            int i = 43;

            string s1 = "Test ";
            s1 += "more test ";
            s1 += i.ToString();
            s1 += "even more test.";

            string s2 = "Test "
                + "more test "
                + i.ToString()
                + "even more test";
becomes
Code:
IL_0001:  ldc.i4.s   43
  IL_0003:  stloc.0
  IL_0004:  ldstr      "Test "
  IL_0009:  stloc.1
  IL_000a:  ldloc.1
  IL_000b:  ldstr      "more test "
  IL_0010:  call       string [mscorlib]System.String::Concat(string,
                                                              string)
  IL_0015:  stloc.1
  IL_0016:  ldloc.1
  IL_0017:  ldloca.s   i
  IL_0019:  call       instance string [mscorlib]System.Int32::ToString()
  IL_001e:  call       string [mscorlib]System.String::Concat(string,
                                                              string)
  IL_0023:  stloc.1
  IL_0024:  ldloc.1
  IL_0025:  ldstr      "even more test."
  IL_002a:  call       string [mscorlib]System.String::Concat(string,
                                                              string)
  IL_002f:  stloc.1
  IL_0030:  ldstr      "Test more test "
  IL_0035:  ldloca.s   i
  IL_0037:  call       instance string [mscorlib]System.Int32::ToString()
  IL_003c:  ldstr      "even more test"
  IL_0041:  call       string [mscorlib]System.String::Concat(string,
                                                              string,
                                                              string)
  IL_0046:  stloc.2

For anything other than trivial string concatenation you would want to investigate the StringBuilder class though, or even see if there is a way to remove the need for concatenation anyway (it can be a security issue as well as a performance one).

Also String.Format(...) is worth a look as it can make this far simpler in terms of your code and can often be localised far easier than building the strings by hand.

Out of interest what kind of strings are you building this way?
 
Huge SQL statements. Basically going through an XML and pulling fields out that need either Inserted, Updated, Deleted... building a SQL and executing it all at once.

Kind of looks something like
"Insert into blah....stuff...; Update blah from (select..stuff.. ) where blah... ; Update blah.... ; Delete from Blah...."...etc

It's one of those programs where you gather the data from a large web form and begin a transaction... do it... if ALL of it runs without failure, commit. otherwise rollback.

Sounds archaic, but it's really the only way to do this one app.


Anyway, I had to do this project based on what I already know... The String builder class isn't part of my knowledge yet. This is one of those projects that had to be done a year ago, but they put it off... now it has to be done like YESTERDAY, if you catch my drift. I'll have to look into stringbuilder for future projects though.

Back to work now. Thanks!
 
I don't know if it's too late for you to impliment; however, the StringBuilder, located in System.Text is very simple to use. Illustrated below.

Visual Basic:
Dim sb As New StringBuilder(5000)
sb.Append("Text to Append")
sb.Append(New String("Some String Variable"))
Return sb.ToString()

C#:
StringBuilder sb = new StringBuilder(5000)
sb.Append("Text to Append");
sb.Append(new String("Some String Variable"));
return sb.ToString();

The 5000 I use to create the StringBuilder, starts the string builder at 5000 bytes in memory. The reason the StringBuilder is so much faster is due to the fact that it alocates more memory than it needs, and fills the memory until it needs more, then it doubles in size.

In my examples above it stats at 5000 bytes, once the StringBuilder reaches 5000 bytes it becomes 10,000 bytes, and so on and soforth. The System.String class realocates the entier length of the string each time you call String.Concat (&=, +=, etc).

In short, to concat the char 'a' 10,000 times, the string builder above would only realocate twice, where as a System.String would realocate many more times taking more CPU cycles.
 
Sounds like it just takes an allocated amount of memory and fills it like using Mid$.

In some app in the past... just for speed purposes, I would declare a fixed length string (Dim someString As String * 64000) to use in string building. Then I'd fill it using Mid$() keeping up with where the start location is. Then dump it where I needed it and trimmed it up.

The only problem was I had to make sure I never had more than 64k in data... or it was truncated.

Interesting. Sounds like StringBuilder is the perfect resolution to the issue. Thanks again.
 
As an aside concatenating strings to make SQL statements isn't that good a plan - it can be error prone when dealing with certain data types (dates being a good example) and can be a major security risk due to the potential of injections.

Parameterised commands or stored procedures are a far better way to go.
 
You say that without knowing the scope of this project. Kind of hard to make that assumption wouldn't you think? In this particular instance, it is the best way. And there is little security risk (trust me, there are FAR worse security issues where I work than this all. <shrugs>).

Anyway, as the saying goes... there are umpteen ways to skin a cat... but in the end, you still have a <drum roll> skinned cat. :D

I do appreciate the feedback on the OP.
 
It is more than a matter of the scope of a project and no assumptions must be made. If you skin the cat with a skill saw you're going to have a nice mess to clean up and not much of a cat to speak of. Concatenating strings to make SQL statements is a bad idea because it is a very bad habit to get into. The first thing that someone who thinks they are a 1773 H4x0r will do is try to inject malicious code through input fields. And... it can be error prone. Regardless of the scope of the project.

The simple reality is that it is just one of those things that you shouldn't do because one of these times it is really going to come back and bite you. Don't get me wrong. You can feel free to do it and you can dismiss our suggestions because just this once won't hurt or because we haven't reviewed your code. But it is something to keep in mind. We are only here to help, not to tell you what to do.
 
I prefer a chainsaw. Makes a lot more noise.

I like having bad habits. It adds character.

And last but not least. I love to do things that people on message boards oppose. Just because I can.

:D

[edit] And BTW, there is no way a hacker would ever get into any of our internal programs... NO WAY. Because anyone smart enough to be able to do anything like that anyway, wouldn't work here. Period.

Computer savvy people : Our users
is like
Car salesmen : Preachers

It's just simply one extreme to the other. hehe
 
Last edited:
Back
Top