string.replace vs stringbuilder, for inserting values in a string ?

  • Thread starter Thread starter Mad Scientist Jr
  • Start date Start date
M

Mad Scientist Jr

In terms of performance, is stringbuilder.replace noticably better or
worse than string.format ? String.format(mystring, myvalue) seems to be
made for this, but you are forced to use {0}, {1} etc as your tags,
where as with string.replace, you can choose tags that are more
readable, like <firstname/>, <lastname/> etc. I was playing around with
code to see how these work (below) - does one perform or scale notably
better? Is one more correct to use? Thanks


################################################################################################################################
HTML "test.aspx"
################################################################################################################################

<%@ Page Language="vb" AutoEventWireup="false"
Codebehind="test.aspx.vb" Inherits="MySite.MyProject.test" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<title>test</title>
<meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
<meta content="Visual Basic .NET 7.1" name="CODE_LANGUAGE">
<meta content="JavaScript" name="vs_defaultClientScript">
<meta content="http://schemas.microsoft.com/intellisense/ie5"
name="vs_targetSchema">
</HEAD>
<body>
<form id="Form1" method="post" runat="server">
<table border="1">
<tr>
<th>
</th>
<th>
Stringbuilder</th>
<th>
String.format</th></tr>
<tr>
<td>Template:</td>
<td><asp:textbox id="TextBoxInA" runat="server"
Columns="20"></asp:textbox></td>
<td><asp:textbox id="TextBoxInB"
runat="server"></asp:textbox></td>
</tr>
<tr>
<td>Tag #1:</td>
<td><asp:TextBox id="TextBoxTagA1" runat="server"
Columns="20"></asp:TextBox></td>
<td>
{0}</td>
</tr>
<tr>
<td>Tag #2:</td>
<td><asp:TextBox id="TextBoxTagA2"
runat="server"></asp:TextBox></td>
<td>
{1}</td>
</tr>
<tr>
<td>Data #1:</td>
<td colspan="2" align="center"><asp:TextBox id="TextBoxData1"
runat="server" Columns="20"></asp:TextBox></td>
</tr>
<tr>
<td>Data #2:</td>
<td colspan="2" align="center"><asp:TextBox id="TextBoxData2"
runat="server"></asp:TextBox></td>
</tr>
<tr>
<td></td>
<td colspan="2" align="center"><asp:Button id="Button1"
runat="server" Text="Insert values"></asp:Button></td>
</tr>
<tr>
<td>Results:</td>
<td><asp:TextBox id="txtOutA" runat="server"
Rows="5"></asp:TextBox></td>
<td>
<asp:TextBox id="txtOutB" runat="server"></asp:TextBox></td>
</tr>
</table>
</form>
</body>
</HTML>

################################################################################################################################
CODEBEHIND "test.aspx.vb"
################################################################################################################################

Public Class test
Inherits System.Web.UI.Page

#Region " Web Form Designer Generated Code "

'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()

End Sub
Protected WithEvents Button1 As System.Web.UI.WebControls.Button
Protected WithEvents TextBoxData1 As
System.Web.UI.WebControls.TextBox
Protected WithEvents TextBoxData2 As
System.Web.UI.WebControls.TextBox
Protected WithEvents TextBoxInA As
System.Web.UI.WebControls.TextBox
Protected WithEvents TextBoxTagA1 As
System.Web.UI.WebControls.TextBox
Protected WithEvents TextBoxTagA2 As
System.Web.UI.WebControls.TextBox
Protected WithEvents TextBoxInB As
System.Web.UI.WebControls.TextBox
Protected WithEvents txtOutA As System.Web.UI.WebControls.TextBox
Protected WithEvents txtOutB As System.Web.UI.WebControls.TextBox

'NOTE: The following placeholder declaration is required by the Web
Form Designer.
'Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object

Private Sub Page_Init(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub

#End Region

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

If Me.IsPostBack() Then
Else
'Put user code to initialize the page here
TextBoxInA.Text = "My name is [first/] [last/]!"
TextBoxInB.Text = "My name is {0} {1}!"

TextBoxTagA1.Text = "[first/]"
TextBoxTagA2.Text = "[last/]"

TextBoxData1.Text = "Joe"
TextBoxData2.Text = "Bob"

txtOutA.Text = ""
txtOutB.Text = ""
End If

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
' STRINGBUILDER METHOD
Dim myStringBuilder1 As System.Text.StringBuilder
myStringBuilder1 = New System.Text.StringBuilder
myStringBuilder1.Append(TextBoxInA.Text)
myStringBuilder1.Replace(TextBoxTagA1.Text, TextBoxData1.Text)
myStringBuilder1.Replace(TextBoxTagA2.Text, TextBoxData2.Text)
txtOutA.Text = myStringBuilder1.ToString

' STRING.FORMAT METHOD
Dim myString1 As String
myString1 = TextBoxInB.Text
txtOutB.Text = myString1.Format(myString1, New Object()
{TextBoxData1.Text, TextBoxData2.Text})

End Sub
End Class
 
The problem with StringBuilder replace is, that you have to do the
replacements sequentially. Also, even for a single replace, it doesn't seem
to perform much better than string.Format.

These are my results:

string.Format with single argument: 703,925 ns
StringBuilder, single Replace: 679,840 ns

string.Format with five arguments: 1,776 us
StringBuilder, five Replaces: 3,492 us

HTH,
Stefan
 
Are you being sarcastic?

No matter. I did a test on 10000 replacements. String.replace took 28
seconds, and String.format took 0.

However

1. how do you use string.format for a variable amounts of variables? i
have only gotten the values list to work if hardcoded:

myString2 = String.Format(myString1, New Object() {"REPLACEMENT",
"REPLACEMENT", "REPLACEMENT"})

What is the New Object supposed to be? How would you create it in a
variable way?

2) the code breaks if your text has too many tags in it. For instance
the following:

myString2 = String.Format("{0}, {1}, {2}", New Object() {"REPLACEMENT
1", "REPLACEMENT 2"})

results in the error: Index (zero based) must be greater than or equal
to zero and less than the size of the argument list.
 
Mad Scientist Jr said:
Are you being sarcastic?

No matter. I did a test on 10000 replacements. String.replace took 28
seconds, and String.format took 0.

However

1. how do you use string.format for a variable amounts of variables? i
have only gotten the values list to work if hardcoded:

myString2 = String.Format(myString1, New Object() {"REPLACEMENT",
"REPLACEMENT", "REPLACEMENT"})

What is the New Object supposed to be? How would you create it in a
variable way?

The way you'd create any array - you're just passing in an array there,
and you can create that any way you want to. Without knowing how you're
getting the list of values, it's hard to say which way is best.
2) the code breaks if your text has too many tags in it. For instance
the following:

myString2 = String.Format("{0}, {1}, {2}", New Object() {"REPLACEMENT
1", "REPLACEMENT 2"})

results in the error: Index (zero based) must be greater than or equal
to zero and less than the size of the argument list.

Well yes - you've effectively provided an invalid format string for the
parameters you've given. Why is that a problem?
 
thanks for your reply
The way you'd create any array - you're just passing in an array there,
and you can create that any way you want to. Without knowing how you're
getting the list of values, it's hard to say which way is best.

i tried using an array:

Dim Array1 As Array
Array1 = Split("a,b,c", ",")
Textbox1.text = String.Format("0={0}, 1={1}, 2={2}", Array1)

which resulted in the error: Index (zero based) must be greater than or
equal to zero and less than the size of the argument list.

The format string has the same number of arguments as the array had
items, so I am not sure why this didn't work. I tried Collection also,
and got the same error.
Well yes - you've effectively provided an invalid format string for the
parameters you've given. Why is that a problem?

Well it's not so much a problem as it's inflexible. If for some reason
I wanted to replace a string but don't have all the parameters, I might
wish to leave the extra tags alone. It's not as big a deal as the above
array problem.
 
Mad Scientist Jr said:
thanks for your reply


i tried using an array:

Dim Array1 As Array
Array1 = Split("a,b,c", ",")
Textbox1.text = String.Format("0={0}, 1={1}, 2={2}", Array1)

which resulted in the error: Index (zero based) must be greater than or
equal to zero and less than the size of the argument list.

The format string has the same number of arguments as the array had
items, so I am not sure why this didn't work. I tried Collection also,
and got the same error.

The problem is that then you're actually passing in the equivalent of

new Object() {Array1};

If you change your code to (in C#):

object[] bits = "a,b,c".Split(',');
textBox1.Text = String.Format("0={0} 1={1} 2={2}", bits);

you'll find it works fine.
Well it's not so much a problem as it's inflexible. If for some reason
I wanted to replace a string but don't have all the parameters, I might
wish to leave the extra tags alone. It's not as big a deal as the above
array problem.

Well, you can always pass in empty strings for those parameters. I'd
far rather String.Format worked the way that it does now than I got
malformed strings because it was silently ignoring effectively invalid
parameters.
 
If you change your code to (in C#):
...
you'll find it works fine.

thanks for this .. it will come in handy
Well, you can always pass in empty strings for those parameters. I'd
far rather String.Format worked the way that it does now than I got
malformed strings because it was silently ignoring effectively invalid
parameters.

true enough.. and also i can always replace the tags i don't have
parameters for, with other tags that can be recognized later...
 
Back
Top