Formatting output using ToString - c#

I am trying to edit my Fuel Consumed line in C# to output the word "gallons" after the numeric quantity. I am not sure how to manipulate ToString to accomplish this. Any help would be appreciated.
// toString method to display object information
public override string ToString()
{ return "\n\nDestination: " + destinationCity +
"\n\nTotal Miles: " + mileageRoundTrip.ToString("F0") +
"\n\nFuel Consumed: " + gallonsUsed.ToString("F1") +
"\n\nFuel Cost Per Gallon: " + gallonsCost.ToString("C") +
"\n\nTotal Fuel Cost for this Trip: " + totalFuelCost.ToString("C") +
"\n\nMPG: " + amountMPG.ToString("F0") +
"\n\nFuel Cost Per Mile: " + costPerMile.ToString("C"); }

Similarly to the concatenation that you are already preforming, you can insert another string literal surrounded by plus + operators after the variable but before any newline characters, this will place the unit of measurement after the numerical value. For example:
+ " gallons" +
Edit:
GreagoryABeamer made some good points in his post for adding adding a robust, systematic implementation of a printed unit. My solution isn't that and if this is at all production or repeated code, that is a much better answer. This solution, however, does present the opportunity for quick use and non-existent overhead (I believe that string literals are concatenated at compile time in c# as well as c++). The code can also look very clean with some aligning of the variables and literals. Perhaps haskish, but sometimes I prefer the quick simplicity. :)

If you'd like to keep your original format including two newline characters, this should do it in a more memory-efficient way while giving you the desired "gallons" suffix.
var sb = new StringBuilder();
sb.AppendFormat("\n\nDestination: {0}", destinationCity);
sb.AppendFormat("\n\nTotal Miles: {0:F0}", mileageRoundTrip);
sb.AppendFormat("\n\nFuel Consumed: {0:F1} gallons", gallonsUsed);
sb.AppendFormat("\n\nFuel Cost Per Gallon: {0:C}", gallonsCost);
sb.AppendFormat("\n\nTotal Fuel Cost for this Trip: {0:C}", totalFuelCost);
sb.AppendFormat("\n\nMPG: {0}", amountMPG);
sb.AppendFormat("\n\nFuel Cost Per Mile: {0:C}", costPerMile);
return sb.ToString();

First, if you really want ToString() to work in this method, you should be using a StringBuilder instead of concantenating. No, concats won't slow things down that much, but you are creating a lot of extra strings behind the scenes to get what you want.
As for adding, you can do something like so:
public override string ToString()
{ var builder = new StringBuilder();
/// more lines here
builder.Append(gallonCost.ToString("C"));
builder.Append(" gallons\n\n");
// etc
return builder.ToString();
}
You can also create internal helper methods for each item to format it how you want and then just concatenate them in the builder. It is cleaner.
But, from an architectural standpoint, there are a lot of smells in this way of doing things. The reason for altering ToString() is to change a representation of the object from default, not to format information for the user interface. If that is the motivation, you are better to do this via a second object and avoid the smell, unless you are making a rule all objects act the same way (still not great, but consistency is easier to follow).
If this is a one-off or temporary app, you might get away with it. If it is personal, it is your own business, so do what you want. For Enterprise software, I would tag this in a code review and force someone to let me know why they used this particular pattern, as it is non-standard and likely against best practices.

Update: See #mvarta's answer which combines format with a StringBuilder for a more readable solution.
I find String.format() more readable because you write the entire template as one string:
return String.format(
"\n\nDestination: {0}\n\nTotal Miles: {1:F0}\n\nFuel Consumed: {2:F1} gallons\n\nFuel Cost Per Gallon: {3:C}\n\nTotal Fuel Cost for this Trip: {4:C}\n\nMPG: {5:F0}\n\nFuel Cost Per Mile: {6:C}",
destinationCity,
mileageRoundTrip,
gallonsUsed,
gallonsCost,
totalFuelCost,
amounts,
costPerMile
);
To add gallons where ever you want, you simple write it there in the template.
Variables are represented in your template with {0}, {1}, etc. where the number is the position of the variable in the following parameters.
All your specific formats in your toString calls are also embedded into the template using {0:C}, {1:F1}, etc. string.Format() is calling toString() for you so it's less verbose.
https://msdn.microsoft.com/en-us/library/system.string.format(v=vs.110).aspx

Related

Shouldn't string.Format be more efficcient than x + "" + y? [duplicate]

I've got a small piece of code that is parsing an index value to determine a cell input into Excel. It's got me thinking...
What's the difference between
xlsSheet.Write("C" + rowIndex.ToString(), null, title);
and
xlsSheet.Write(string.Format("C{0}", rowIndex), null, title);
Is one "better" than the other? And why?
My initial preference (coming from a C++ background) was for String.Format. I dropped this later on due to the following reasons:
String concatenation is arguably "safer". It happened to me (and I've seen it happen to several other developers) to remove a parameter, or mess up the parameter order by mistake. The compiler will not check the parameters against the format string and you end up with a runtime error (that is, if you're lucky enough not to have it in an obscure method, such as logging an error). With concatenation, removing a parameter is less error prone. You could argue the chance of error is very small, but it may happen.
- String concatenation allows for null values, String.Format does not. Writing "s1 + null + s2" does not break, it just treats the null value as String.Empty. Well, this may depend on your specific scenario - there are cases where you'd like an error instead of silently ignoring a null FirstName. However even in this situation I personally prefer checking for nulls myself and throwing specific errors instead of the standard ArgumentNullException I get from String.Format.
String concatenation performs better. Some of the posts above already mention this (without actually explaining why, which determined me to write this post :).
Idea is the .NET compiler is smart enough to convert this piece of code:
public static string Test(string s1, int i2, int i3, int i4,
string s5, string s6, float f7, float f8)
{
return s1 + " " + i2 + i3 + i4 + " ddd " + s5 + s6 + f7 + f8;
}
to this:
public static string Test(string s1, int i2, int i3, int i4,
string s5, string s6, float f7, float f8)
{
return string.Concat(new object[] { s1, " ", i2, i3, i4,
" ddd ", s5, s6, f7, f8 });
}
What happens under the hood of String.Concat is easy to guess (use Reflector). The objects in the array get converted to their string via ToString(). Then the total length is computed and only one string allocated (with the total length). Finally, each string is copied into the resulting string via wstrcpy in some unsafe piece of code.
Reasons String.Concat is way faster? Well, we can all have a look what String.Format is doing - you'll be surprised at the amount of code required to process the format string. On top of this (I've seen comments regarding the memory consumption), String.Format uses a StringBuilder internally. Here's how:
StringBuilder builder = new StringBuilder(format.Length + (args.Length * 8));
So for every passed argument, it reserves 8 characters. If the argument is a one-digit value, then too bad, we have some wasted space. If the argument is a custom object returning some long text on ToString(), then there might be even some reallocation needed (worst-case scenario, of course).
Compared to this, the concatenation only wastes the space of the object array (not too much, taking into account it's an array of references). There's no parsing for format specifiers and no intermediary StringBuilder. The boxing/unboxing overhead is present in both methods.
The only reason I'd go for String.Format is when localization is involved. Putting format strings in resources allows you to support different languages without messing with the code (think about scenarios where formatted values change order depending on the language, i.e. "after {0} hours and {1} minutes" may look quite different in Japanese :).
To sum up my first (and quite long) post:
best way (in terms of performance vs. maintainability/readability) for me is using string concatenation, without any ToString() calls
if you're after performance, make the ToString() calls yourself to avoid boxing (I'm somewhat biased towards readability) - same as first option in your question
if you're showing localized strings to the user (not the case here), String.Format() has an edge.
Before C# 6
To be honest, I think the first version is simpler - although I'd simplify it to:
xlsSheet.Write("C" + rowIndex, null, title);
I suspect other answers may talk about the performance hit, but to be honest it'll be minimal if present at all - and this concatenation version doesn't need to parse the format string.
Format strings are great for purposes of localisation etc, but in a case like this concatenation is simpler and works just as well.
With C# 6
String interpolation makes a lot of things simpler to read in C# 6. In this case, your second code becomes:
xlsSheet.Write($"C{rowIndex}", null, title);
which is probably the best option, IMO.
I think the first option is more readable and that should be your primary concern.
xlsSheet.Write("C" + rowIndex.ToString(), null, title);
string.Format uses a StringBuilder under the hood (check with reflector) so it won't have any performance benefit unless you are doing a significant amount of concatenation. It will be slower for your scenario but the reality is this micro performance optimisation decision is inappropriate most of the time and you should really be focusing on the readability of your code unless you are in a loop.
Either way, write for readability first and then use a performance profiler to identify your hotspots if you really think you have performance concerns.
For a simple case where it's a simple single concatenation, I feel that it's not worth the complexity of string.Format (and I haven't tested, but I suspect that for a simple case like this, string.Format might be slightly slower, what with the format string parsing and all). Like Jon Skeet, I prefer to not explicitly call .ToString(), since that will be done implicitly by the string.Concat(string, object) overload, and I think the code is cleaner-looking and easier to read without it.
But for more than a few concatenations (how many is subjective), I definitely prefer string.Format. At a certain point I think that both readability and performance suffer unnecessarily with concatenation.
If there are many parameters to the format string (again, "many" is subjective), I usually prefer to include commented indices on the replacement arguments, lest I lose track of which value goes to which parameter. A contrived example:
Console.WriteLine(
"Dear {0} {1},\n\n" +
"Our records indicate that your {2}, \"{3}\", is due for {4} {5} shots.\n" +
"Please call our office at 1-900-382-5633 to make an appointment.\n\n" +
"Thank you,\n" +
"Eastern Veterinary",
/*0*/client.Title,
/*1*/client.LastName,
/*2*/client.Pet.Animal,
/*3*/client.Pet.Name,
/*4*/client.Pet.Gender == Gender.Male ? "his" : "her",
/*5*/client.Pet.Schedule[0]
);
Update
It occurs to me that the example I've given is a bit confusing, because it appears that I've used both concatenation and string.Format here. And yes, logically and lexically, that's what I've done. But the concatenations will all be optimized away by the compiler1, since they're all string literals. So at run-time, there will be a single string. So I guess I should say that I prefer to avoid many concatenations at run time.
Of course, most of this topic is out of date now, unless you're still stuck using C# 5 or older. Now we have interpolated strings, which for readability, are far superior to string.Format, in almost all cases. These days, unless I'm just concatenating a value directly to the beginning or end of a string literal, I almost always use string interpolation. Today, I'd write my earlier example like this:
Console.WriteLine(
$"Dear {client.Title} {client.LastName},\n\n" +
$"Our records indicate that your {client.Pet.Animal}, \"{client.Pet.Name}\", " +
$"is due for {(client.Pet.Gender == Gender.Male ? "his" : "her")} " +
$"{client.Pet.Schedule[0]} shots.\n" +
"Please call our office at 1-900-382-5633 to make an appointment.\n\n" +
"Thank you,\n" +
"Eastern Veterinary"
);
You do lose compile-time concatenation this way. Each interpolated string gets turned into a call to string.Format by the compiler, and their results are concatenated at run time. That means this is a sacrifice of run-time performance for readability. Most of the time, it's a worthwhile sacrifice, because the run-time penalty is negligible. In performance critical code, however, you may need to profile different solutions.
1
You can see this in the C# specification:
... the following constructs are permitted in constant expressions:
...
The predefined + ... binary operator...
You can also verify it with a little code:
const string s =
"This compiles successfully, " +
"and you can see that it will " +
"all be one string (named `s`) " +
"at run time";
If your string was more complex with many variables being concatenated, then I would choose the string.Format(). But for the size of string and number of variables being concatenated in your case, I'd go with your first version, it's more spartan.
That example is probably too trivial to notice a difference. In fact, I think in most cases the compiler can optimize away any difference at all.
However, if I had to guess I'd give string.Format() an edge for more complicated scenarios. But that's more of a gut feeling that's it's likely to do a better job utilizing a buffer instead of producing multiple immutable strings, and not based on any real data.
I have taken a look at String.Format (using Reflector) and it actually creates a StringBuilder then calls AppendFormat on it. So it is quicker than concat for multiple stirngs. Quickest (I believe) would be creating a StringBuilder and doing the calls to Append manually. Of course the number of "many" is up for guessing.
I would use + (actually & becuase I am a VB programmer mostly) for something as simple as your example. As it gets more complex I use String.Format. If there are LOTS of variables then I would go for a StringBuilder and Append, for example, we have code that builds code, there I use one line of actual code to output one line of generated code.
There seems to be some speculation about how many strings get created for each of these operations, so lets take a few simple examples.
"C" + rowIndex.ToString();
"C" is already a string.
rowIndex.ToString() creates another string. (#manohard - no boxing of rowIndex will occur)
Then we get the final string.
If we take the example of
String.Format("C(0)",rowIndex);
then we have "C{0}" as a string
rowIndex gets boxed to be passed to the function
A new stringbuilder is created
AppendFormat is called on the string builder - I don't know the details of how AppendFormat functions but lets assume it is ultra efficient, it is still going to have to convert the boxed rowIndex into a string.
Then convert the stringbuilder into a new string.
I know that StringBuilders attempt to prevent pointless memory copies from taking place but the String.Format still ends up with extra overhead compared to the plain concatenation.
If we now take an example with a few more strings
"a" + rowIndex.ToString() + "b" + colIndex.ToString() + "c" + zIndex.ToString();
we have 6 strings to start with, which will be the same for all cases.
Using concatenation we also have 4 intermediate strings plus the final result. It is those intermediate results that are eliminated by using String,Format (or a StringBuilder).
Remember that to create each intermediate string, the previous one must be copied to a new memory location, it is not just the memory allocation that is potentially slow.
I like String.Format because can make your formatted text much easier to follow and read than inline concatenation, also its much more flexible allowing you to format your parameters, however for short uses like yours I see no problem about concatenating.
For concatenations inside loops or in big strings you should always try to use the StringBuilder class.
I agree with alot of points above, another point that I believe should be mentioned is code maintainability. string.Format allows for easier changing of code.
i.e. I have a message
"The user is not authorized for location " + location or
"The User is not authorized for location {0}"
if I ever wanted to change the message to say:
location + " does not allow this User Access" or
"{0} does not allow this User Access"
with string.Format all I have to do is change the string.
for concatenation I have to modify that message
if used in multiple places can save allot of time.
I was under the impression that string.format was faster it seems to be 3 x slower in this test
string concat = "";
System.Diagnostics.Stopwatch sw1 = new System.Diagnostics.Stopwatch ();
sw1.Start();
for (int i = 0; i < 10000000; i++)
{
concat = string.Format("{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}","1", "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" , "10" , i);
}
sw1.Stop();
Response.Write("format: " + sw1.ElapsedMilliseconds.ToString());
System.Diagnostics.Stopwatch sw2 = new System.Diagnostics.Stopwatch();
sw2.Start();
for (int i = 0; i < 10000000; i++)
{
concat = "1" + "2" + "3" + "4" + "5" + "6" + "7" + "8" + "9" + "10" + i;
}
sw2.Stop();
string.format took 4.6 sec and when using '+' it took 1.6 secs.
About performance:
void Main()
{
var start = CurrentTimeMillis();
for (var i = 0; i < 1000000; i++)
{
var s = "Hi " + i.ToString() + "; Hi to you " + (i * 2).ToString();
}
var end = CurrentTimeMillis();
Console.WriteLine("Concatenation = " + ((end - start)).ToString() + " millisecond");
start = CurrentTimeMillis();
for (var i = 0; i < 1000000; i++)
{
var s = String.Format("Hi {0}; Hi to you {1}", i, +i * 2);
}
end = CurrentTimeMillis();
Console.WriteLine("Format = " + ((end - start)).ToString() + " millisecond");
start = CurrentTimeMillis();
for (var i = 0; i < 1000000; i++)
{
var s = String.Concat("Hi ", i.ToString(), "; Hi to you ", (i * 2).ToString());
}
end = CurrentTimeMillis();
Console.WriteLine("Strng.concat = " + ((end - start)).ToString() + " millisecond");
start = CurrentTimeMillis();
for (int i = 0; i < 1000000; i++)
{
StringBuilder bldString = new StringBuilder("Hi ");
bldString.Append(i).Append("; Hi to you ").Append(i * 2);
}
end = CurrentTimeMillis();
Console.WriteLine("String Builder = " + ((end - start)) + " millisecond");
}
private static readonly DateTime Jan1st1970 = new DateTime
(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static long CurrentTimeMillis()
{
return (long)(DateTime.UtcNow - Jan1st1970).TotalMilliseconds;
}
Result
Concatenation = 69 millisecond
Format = 142 millisecond
Strng.concat = 62 millisecond
String Builder = 91 millisecond
To make this a fair comparison, I instantiate a new StringBuilder rather than one created outside the loop (which is likely to be faster due to the looping append at the end of one builder's re-allocation space).
string.Format is probably a better choice when the format template ("C{0}") is stored in a configuration file (such as Web.config / App.config)
I did a bit of profiling of various string methods including string.Format, StringBuilder and string concatenation. String concatenation almost always outperformed the other methods of building strings. So, if performance is key, then its better. However, if performance is not critical then I personally find string.Format to be easier to follow in code. (But that's a subjective reason) StringBuilder however, is probably most efficient with respect to memory utilization.
I prefer String.Format regarding to performance
String concatenation takes more memory compared to String.Format. So best way to concatenate strings is using String.Format or System.Text.StringBuilder Object.
Let's take first case: "C" + rowIndex.ToString()
Let's assume rowIndex is a value type so ToString() method has to Box to convert the value to String and then CLR creates memory for the new string with both values included.
Where as string.Format expects object parameter and takes in rowIndex as an object and converts it to string internally offcourse there will be Boxing but it's intrinsic and also it's won't take up as much memory as in first case.
For short strings it won't matter that much I guess...

Is there a difference between concatenation and place holding in C# output or is it a matter of preference?

Just started working with C# for the first time, and while looking through the tutorial, I found nothing on the difference between the Concatenation (console.writeline("Hello" + user) where user is a string variable) and the place holder (console.writeline("Hello {0}" , user) where user is a string variable) methods for output. Is there a difference or is it simply which way you find easier
Its not really specific to C#, lots of languages support both styles. The latter form is usually thought of as 'safer', but I can't quote any specific reason why. It is useful if the item needs to appear in more than 1 place, or if you want to save the format string as a constant. Take a look at this thread for more info: When is it better to use String.Format vs string concatenation?.
Using string formatters, as opposed to string concatenation, is almost entirely about readability. What they actually do, and even how they perform, is close enough to the same.
For such a simple case both look all right, but when you have a complex string with lots of values mixed in format strings can end up looking a lot nicer:
Here's a better example:
string output = "Hello " + username + ". I have spent " + executionTime + " seconds trying to figure out that the answer to life is: " + output;
vs
string output = string.Format("Hello {0}. I have spent {1} seconds trying to figure out that the answer to life is: {2}"
, username, executionTime, output);
As Matt said Place holding is considered as the safer approach then the simple concatenation, but I am not sure for that reasons(I need to explore on it). But yes one thing is sure that Place Holding is a bit costly operation then Concatenation in terms of Performance. Check this Blog entry "Formatting Strings" by Jon Skeet.
Although performance will be effected significantly only if you are using Place Holders for like thousands times or so.

Efficiency of Indexed Placeholders

There are several places where you can use the indexed placeholder syntax in C#, ie.
// Assume some object is available with 2 string properties
Console.Writeline("Hello {0}, today is {1}", obj.Username, obj.DayOfWeek);
Is that more efficient than using the string concatenation operator to build the string? ie.
Console.Writeline("Hello " + obj.Username + " today is " + obj.DayOfWeek);
Obviously the {0} ... {n} syntax is cleaner if you're doing something complicated -- but which code is more efficient (lower memory footprint and or execution time?)
Well the first version has to parse the string and interpret it, before doing the actual string concatenation. So one would expect the first method to be slower, and potentially more memory-intensive, no?
But unless you're doing vast amounts of string processing, it's unlikely to be an issue.
Don't think about it, use the formatting one. If you worry about memory/execution time with such a method, you have other problems.

C# better way to do this?

Hi I have this code below and am looking for a prettier/faster way to do this.
Thanks!
string value = "HelloGoodByeSeeYouLater";
string[] y = new string[]{"Hello", "You"};
foreach(string x in y)
{
value = value.Replace(x, "");
}
You could do:
y.ToList().ForEach(x => value = value.Replace(x, ""));
Although I think your variant is more readable.
Forgive me, but someone's gotta say it,
value = Regex.Replace( value, string.Join("|", y.Select(Regex.Escape)), "" );
Possibly faster, since it creates fewer strings.
EDIT: Credit to Gabe and lasseespeholt for Escape and Select.
While not any prettier, there are other ways to express the same thing.
In LINQ:
value = y.Aggregate(value, (acc, x) => acc.Replace(x, ""));
With String methods:
value = String.Join("", value.Split(y, StringSplitOptions.None));
I don't think anything is going to be faster in managed code than a simple Replace in a foreach though.
It depends on the size of the string you are searching. The foreach example is perfectly fine for small operations but creates a new instance of the string each time it operates because the string is immutable. It also requires searching the whole string over and over again in a linear fashion.
The basic solutions have all been proposed. The Linq examples provided are good if you are comfortable with that syntax; I also liked the suggestion of an extension method, although that is probably the slowest of the proposed solutions. I would avoid a Regex unless you have an extremely specific need.
So let's explore more elaborate solutions and assume you needed to handle a string that was thousands of characters in length and had many possible words to be replaced. If this doesn't apply to the OP's need, maybe it will help someone else.
Method #1 is geared towards large strings with few possible matches.
Method #2 is geared towards short strings with numerous matches.
Method #1
I have handled large-scale parsing in c# using char arrays and pointer math with intelligent seek operations that are optimized for the length and potential frequency of the term being searched for. It follows the methodology of:
Extremely cheap Peeks one character at a time
Only investigate potential matches
Modify output when match is found
For example, you might read through the whole source array and only add words to the output when they are NOT found. This would remove the need to keep redimensioning strings.
A simple example of this technique is looking for a closing HTML tag in a DOM parser. For example, I may read an opening STYLE tag and want to skip through (or buffer) thousands of characters until I find a closing STYLE tag.
This approach provides incredibly high performance, but it's also incredibly complicated if you don't need it (plus you need to be well-versed in memory manipulation/management or you will create all sorts of bugs and instability).
I should note that the .Net string libraries are already incredibly efficient but you can optimize this approach for your own specific needs and achieve better performance (and I have validated this firsthand).
Method #2
Another alternative involves storing search terms in a Dictionary containing Lists of strings. Basically, you decide how long your search prefix needs to be, and read characters from the source string into a buffer until you meet that length. Then, you search your dictionary for all terms that match that string. If a match is found, you explore further by iterating through that List, if not, you know that you can discard the buffer and continue.
Because the Dictionary matches strings based on hash, the search is non-linear and ideal for handling a large number of possible matches.
I'm using this methodology to allow instantaneous (<1ms) searching of every airfield in the US by name, state, city, FAA code, etc. There are 13K airfields in the US, and I've created a map of about 300K permutations (again, a Dictionary with prefixes of varying lengths, each corresponding to a list of matches).
For example, Phoenix, Arizona's main airfield is called Sky Harbor with the short ID of KPHX. I store:
KP
KPH
KPHX
Ph
Pho
Phoe
Ar
Ari
Ariz
Sk
Sky
Ha
Har
Harb
There is a cost in terms of memory usage, but string interning probably reduces this somewhat and the resulting speed justifies the memory usage on data sets of this size. Searching happens as the user types and is so fast that I have actually introduced an artificial delay to smooth out the experience.
Send me a message if you have the need to dig into these methodologies.
Extension method for elegance
(arguably "prettier" at the call level)
I'll implement an extension method that allows you to call your implementation directly on the original string as seen here.
value = value.Remove(y);
// or
value = value.Remove("Hello", "You");
// effectively
string value = "HelloGoodByeSeeYouLater".Remove("Hello", "You");
The extension method is callable on any string value in fact, and therefore easily reusable.
Implementation of Extension method:
I'm going to wrap your own implementation (shown in your question) in an extension method for pretty or elegant points and also employ the params keyword to provide some flexbility passing the arguments. You can substitute somebody else's faster implementation body into this method.
static class EXTENSIONS {
static public string Remove(this string thisString, params string[] arrItems) {
// Whatever implementation you like:
if (thisString == null)
return null;
var temp = thisString;
foreach(string x in arrItems)
temp = temp.Replace(x, "");
return temp;
}
}
That's the brightest idea I can come up with right now that nobody else has touched on.

Is it worth using StringBuilder in web apps?

In web app I am splitting strings and assigning to link names or to collections of strings. Is there a significant performance benefit to using stringbuilder for a web application?
EDIT: 2 functions: splitting up a link into 5-10 strings. THen repackaging into another string. Also I append one string at a time to a link everytime the link is clicked.
How many strings will you be concatenating? Do you know for sure how many there will be, or does it depend on how many records are in the database etc?
See my article on this subject for more details and guidelines - but basically, being in a web app makes no difference to how expensive string concatenation is vs using a StringBuilder.
EDIT: I'm afraid it's still not entirely clear from the question exactly what you're doing. If you've got a fixed set of strings to concatenate, and you can do it all in one go, then it's faster and probably more readable to do it using concatenation. For instance:
string faster = first + " " + second + " " + third + "; " + fourth;
string slower = new StringBuilder().Append(first)
.Append(" ")
.Append(second)
.Append(" ")
.Append(third)
.Append("; ")
.Append(fourth)
.ToString();
Another alternative is to use a format string of course. This may well be the slowest, but most readable:
string readable = string.Format("{0} {1} {2}; {3}",
first, second, third, fourth);
The part of your question mentioning "adding a link each time" suggests using a StringBuilder for that aspect though - anything which naturally leads to a loop is more efficient (for moderate to large numbers) using StringBuilder.
You should take a look at this excellent article by Jon Skeet about concatenating strings.
Yes, concatenating regular strings is expensive (really appending on string on to the end of another). Each time a string is changed, .net drops the old string and creates a new one with the new values. It is an immutable object.
EDIT:
Stringbuilder should be used with caution, and evaluated like any other approach. Sometimes connactenting two strings together will be more efficient, and should be evaluated on a case by case basis.
Atwood has an interesting article related to this.
Why would the performance be any different in a web application or a winforms application?
Using stringbuilder is a matter of good practice because of memory and object allocation, the rules apply no matter why you are building the code.
If you're making the string in a loop with a high number of iterations, then it's a good idea to use stringbuilder. Otherwise, string concatenation is your best bet.
FIRSTLY, Are you still writing this application? If yes then STOP Performance tuning!
SECONDLY, Prioritise Correctness over Speed. Readability is way more important in the long run for obvious reasons.
THIRDLY, WE don't know the exact situation and code you are writing. We can't really advise you if this micro optimisation is important to the performance of your code or not. MEASURE the difference. I highly recommend Red Gate's Ants Profiler.

Categories