Click to See Complete Forum and Search --> : Quirk String.Remove vs StringBuilder.Remove


TT(n)
March 23rd, 2009, 02:49 AM
I found a quirk that may be helpful for someone else to know, if they run into the same mistake.
EDIT: By quirk, I mean that a newbie may not be able to predict the behavior, thus causing them to make a mistake.


You can remove part of a string "In place" by using the StringBuilder.Remove (http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.remove(VS.71).aspx) method.

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim sb As New System.Text.StringBuilder("randomstring2342")

sb.Remove(0, 6)

MessageBox.Show(sb.ToString)
End Sub


However, you can not remove it "In place", if you are using String.Remove (http://msdn.microsoft.com/en-us/library/d8d7z2kk.aspx).

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim s As String = "randomstring2342"

s.Remove(0, 6)

MessageBox.Show(s)
End Sub


You have to use the return value instead.

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim s As String = "randomstring2342"

s = s.Remove(0, 6)

MessageBox.Show(s)
End Sub



Although, the stringbuilder allows you to use the return value too.
One might not expect that you'd be able to set it "In place" or by it's "Return value".
You may expect that a String can be set in place though.:ehh:

Oblio
March 23rd, 2009, 07:51 AM
it is not a quirk. from the documentation of String:
"Once you assign a string to a String variable, that string is immutable, which means you cannot change its length or contents. When you alter a string in any way, Visual Basic creates a new string and abandons the previous one. The String variable then points to the new string."


and stringbuilder

"This class represents a string-like object whose value is a mutable sequence of characters. The value is said to be mutable because it can be modified once it has been created by appending, removing, replacing, or inserting characters."

TT(n)
March 23rd, 2009, 08:27 AM
It so is a quirk.
I didn't say a bug, which would disagree with the documentation.

I was being helpful, not asking a question.

Shuja Ali
March 23rd, 2009, 01:43 PM
No it is not a quirk. Strings are immutable by design, that is why you can't do that with a string.

Immutable means that String becomes Thread Safe and has a better performance.

Oblio
March 23rd, 2009, 02:42 PM
quirk
1 a: an abrupt twist or curve b: a peculiar trait

a = no
b = no

TT(n)
March 23rd, 2009, 03:06 PM
I've known for years that strings are immutable.
Stringbuilder has better performance if you are going to manipulate lots of strings. I'm not sure what performance gain Shuja is speaking of.


It recently came up while I was teaching someone how to work with strings. Its still not obvious or expected to someone who doesn't already know.

Hence Vagary (C=True), a unpredictable twist that actually makes sense in the end.

Yes it's a quirk.
I win.

Oblio
March 23rd, 2009, 03:38 PM
the sun came up

quirk - the sun came up and i could not see it ??????????? it was a cloud covered morning.

a lot of people would see this post and decide that strings do something quirky, and that is not the case.

if your post had been Strings and StringBuilder Different, well DUH! but if it is important for you to win this semantic debate, claim victory.

Dim s As String = "randomstring2342"

Dim sb As New System.Text.StringBuilder()

sb.Append(s)
'at this point s and sb have the same values stored "randomstring2342"

s.Remove(0, 6) 'this does nothing to s
s = s.Remove(0, 6) 's now equals "string2342"

sb.Remove(0, 6) 'sb now equals "string2342"

TT(n)
March 23rd, 2009, 05:45 PM
if it is important for you to win this semantic debate, claim victory.

Wow, I guess you're the better person, for allowing me to claim victory.
Clearly you just want to help other members out, and this is not some immature attempt to make yourself look better.

Oblio
March 23rd, 2009, 06:00 PM
You brought up winning, I didn't. I don't care. There is nothing "quirky" about your examples. String and StringBuilder are different.

dglienna
March 24th, 2009, 12:28 AM
He won...

Shuja Ali
March 24th, 2009, 03:54 AM
Basically you are missing the point of why immutability is required at first place.

Read the background section here
http://en.wikipedia.org/wiki/Immutable_object

TT(n)
March 24th, 2009, 07:59 AM
Shuja,

Although I think you are genuiely trying to be helpful, as you can see I don't need any schooling with simple wikipedia links.

As I've illustrated already, I was teaching someone that ran into an issue with the Remove method, that caused his program to crash.
I learned how to use strings, and StringBuilder way back in 2004-2005. At that time, I also ran into the issue when coverting an example that used StringBuilders, into one that uses regular strings. Suddenly the Remove function fails(as it should), and I had to find out why. A quirky obstacle at the time.

Sure it was a newbie mistake, or undersight.
That's why I posted to help others, that don't know yet.
It doesn't necessarily mean that they are dumb either, as Oblio implies.


OFF TOPIC(some more)
----------------------
Speed Strings vs. StringBuilder.

There are alot indications that StringBuilder is generally faster, and only a few that show Stings having a slight speed advantage in isolated cases.
Lot's of variables can taint any single deterministic test, so I can only rely on what I've seen over the years:
StringBuilder = good

With Strings a new memory address is allocated each time, so this seems to be one possible reason that Strings lose the speed advantage they should enjoy, when there are many manipulations.

Here is my isolated test on one machine (xp sp3 AMD ASUS).
I used both the append method, and the remove method, and found StringBuilder definately faster in all cases.

.REMOVE (3.8... x faster)
String
00:00:00.0011440

StringBuilder
00:00:00.0002992

This test used a string with a length of only a 1000.
This speed difference only increases as the string gets larger.:)



Dim StringTimeSpan As Int32
Dim BuilderTimeSpan As Int32
Private tString As String
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
tString = "ha98h34fp98hap9w38y9prhshefhkshahsdifhk34hlkh2lkhlk34h2lkjh3rlk2hlhfh3h839hf98hs9dfg90s8ydf908sydf8s9hdf9h9hgf98sh98hdfg9s8hd9ghs9dhg9s8hf9gywy9yyy8yf8yw8etwtr3jhrg2j3grjg23uhrh0b29u0u0bu0bu209n023n 04707v2 08975 90275 0v729073095702n03475n0720934750n237045027vn50720572075b072n507n20785n0287n0578n20785nv2f095378j92387502385nh209875hn02978hj50782hn0572h57777777777777777777777777777777777777777777777777777777777777777777777777gggggggggggggggggggggggggggggggggggggggggggggggggggggasdgfawet34tgn8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888"
' tString &= tString 'double the length...
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If UseString.CheckState = CheckState.Checked Then UseStringTest()
If UseBuilder.CheckState = CheckState.Checked Then UseBuilderTest()
End Sub
Private Sub UseStringTest()
Dim myStopwatch As Stopwatch = New Stopwatch
Dim LoopLimit As Int32 = tString.Length
Dim TestString As String = tString
Dim myTimeSpan As New TimeSpan
myStopwatch.Reset()
myStopwatch.Start()
For i As Int32 = 1 To LoopLimit - 1
TestString = TestString.Remove(0, 1)
Next
myStopwatch.Stop()
myTimeSpan = myStopwatch.Elapsed
StringTimeSpan = myTimeSpan.Milliseconds
UsingString.Text = myTimeSpan.ToString
End Sub
Private Sub UseBuilderTest()
Dim myStopwatch As Stopwatch = New Stopwatch
Dim LoopLimit As Int32 = tString.Length
Dim TestAppend As New System.Text.StringBuilder("")
Dim myTimeSpan As New TimeSpan
TestAppend.Append(tString)
myStopwatch.Reset()
myStopwatch.Start()
For i As Int32 = 1 To LoopLimit - 1
TestAppend.Remove(0, 1)
Next
myStopwatch.Stop()
myTimeSpan = myStopwatch.Elapsed
BuilderTimeSpan = myTimeSpan.Milliseconds
UsingBuilder.Text = myTimeSpan.ToString
End Sub



If anyone comes up with different results, or has an issue with the testing code above, please post and correct me.

Shuja,
Did you mean safety or speed performance?
Or both?

Oblio
March 24th, 2009, 01:25 PM
STOP putting words in my mouth. "It doesn't necessarily mean that they are dumb either, as Oblio implies." I didn't imply anything. I said
1 - it isn't quirky
2 - they are different

Shuja Ali
March 24th, 2009, 01:57 PM
Although I think you are genuiely trying to be helpful, as you can see I don't need any schooling with simple wikipedia links. I was not trying to do any schooling though. Usually if a thread is posted here, it implies that it is a question.
When it is a FAQ or just an information, it should go into other section.

With regards to your test, keep in mind, StringBuilder has been made available for different kind of operations and string has a different use. Remove method would create a new instance of string in memory, however StringBuilder works in a different way.

TT(n)
March 24th, 2009, 03:04 PM
Usually if a thread is posted here, it implies that it is a question. Well did you actually read the posts. It's clearly not a question.
Then I re-enforced this fact again during the thread.
EDIT: And no it shouldn't be moved to another section. Do not.


With regards to your test, keep in mind, StringBuilder has been made available for different kind of operations and string has a different use. Remove method would create a new instance of string in memory, however StringBuilder works in a different way.
Wow really.


You didn't answer my real question about what kind of performance gain you were speaking of.
Safety, speed, or both?
Your sentence can be interpreted in several ways.
Immutable means that String becomes Thread Safe and has a better performance.
Does And mean Also?

It's only safer in some cases for newbies, that may not be keeping track of things, or changing the value between threads.
It's not really an issue for me, when I use it.
Obviously I've shown that StringBuilder is faster in most cases, and so has better performance.


Basically you are missing the point of why immutability is required at first place. Ya okay, where did that come from?
I'm not the one missing any points here.

Oblio
March 24th, 2009, 03:39 PM
i would agree, this should be moved somewhere else since there wasn't a question asked or answered.

TT(n)
March 24th, 2009, 03:48 PM
STOP putting words in my mouth. ...." I didn't imply anything. I said

Actually words said and words implied are different, however you did say this:
if your post had been Strings and StringBuilder Different, well DUH!
Which does put your own words back into your mouth.

Your whole argument implies that a normally intelligent person would not and should not be making this mistake.
There is no quirk for you, in your mind, so you think it couldn't possibly be an issue for others.

Please put me on your ignore list Oblio.
You certainly will be on mine.

TT(n)
March 24th, 2009, 03:53 PM
i would agree, this should be moved somewhere else since there wasn't a question asked or answered



There is no official requirement for threads.
This is a place of discussion, and this thread is just fine here.

I would be highly offended if it were moved, and I don't think Shuja is a vengful person like that.


How small.

Oblio
March 24th, 2009, 04:12 PM
why don't you just stop? or are you the only one allowed to have an opinion? if i wanted it moved because i didn't like you, i would have said so, or not said anything at all.

this is the wrong place to be if you want your opinion to be the only one allowed.

you put words in my mouth, now calling me names. that is offensive.

TT(n)
March 24th, 2009, 04:18 PM
Common now, are you really going to act like the suggestion to move the thread, is purely objective.

Shuja Ali
March 25th, 2009, 01:55 PM
Well did you actually read the posts. It's clearly not a question.
Then I re-enforced this fact again during the thread.
EDIT: And no it shouldn't be moved to another section. Do not.First of all your post mentioned quirk, which is not a correct word, if you read why immutability is desired at first place. Second is that no body gives orders here. Your "Do Not" does not imply that we cannot move the thread into some other section. If you think logically, posting this in a FAQ would be helpful (of course with a changed title) to lot of people rather than posting in a forum. FAQ has an index where people can easily look for what they are searching where as in Forums they have to search for the keyword "quirk" to get to your thread. unlike you i was giving a suggestion not an order to post it in a separate section with a proper heading. I repeat my words, string being immutable is not a quirk (-noun "a sudden twist or turn").

You didn't answer my real question about what kind of performance gain you were speaking of.
Safety, speed, or both?
Your sentence can be interpreted in several ways.
Does And mean Also?Here is my explanation of why it is not a quirk and why it is a good thing that it got introduced in .NET:
Protection:
Immutable objects once instantiated cannot be changed so immutable object can flow to different layers of the applicationa nd we will be sire that it is not being altered by any layer. You must be knowing that string in .NET is a reference type and you must also be knowing that when a reference types are passed vetween methods, it is the actual reference that gets passed and not the value, which implies that the called method can chnge the value of that reference type. But because string type is immutable you avoid such kind of un-necessary error checking within your code.

Performance:
With your knowledge you will know that copying objects is much faster than copying the data. So there you go, the performance boost. However, this also means that when a string is used a lot, it will degrade the performance because if you do something like this in a loop, the GC has to collect extra pile of objects which were un-wanted in the first place. Dim temp as string, i as Integer
For i = 1 to 10000
temp = temp + "New value"
NextThe code above will create 10000 objects out of which 9999 are useless because they are not being used anywhere. So the GC has to do some extra cleaning up. For this case, you will use Stringbuilder. This is what I meant when I said that strings are meant for a different operation and StringBuilder is meant for different kind of operation. I guess even though people are experienced and know the facts we still need to explain small bits at times.

Scalability:
In a multi-threaded environment an immutable object (in this case string) would never change simply because it is immutable. If it were supposed to be mutable, you would not be sure which thread would change the value of the object. So there you go again, thread safety. Immutability by design would make sure that you don't fall into race conidtions.


It's only safer in some cases for newbies, that may not be keeping track of things, or changing the value between threads.
It's not really an issue for me, when I use it.
Obviously I've shown that StringBuilder is faster in most cases, and so has better performance.This is the reason why I chose to write that strings are meant for different operations that stringbuilder. I don't think that it is safer for newbies and not so safer for experienced programmer because experienced programmers know it all. This is wrong notion and sometimes experienced programmers write code which is far less maintainable and understandable than the code written by newbee.


Ya okay, where did that come from?
I'm not the one missing any points here. No one is missing any points here. I am still saying that it is not a quirk and newbie should know that the immutability of the string data type is because of design and because of some purpose and it is NOT a quirk.

TT(n)
March 25th, 2009, 04:30 PM
I think a big misunderstanding is the definition of quirk.
Quirk had a closer third definition, which was Vagary.
I had mentioned that, but it seems to be easily overlooked.
Check Vagary, and the word unpredictable fits pretty well, for newbies.
Twist is synonymous with unpredictable. We're not talking about the dance style either. :)

Bugs and errors, are usually on the VB side, including documentation.
Quirks and mistakes are usually on the developer side.
Sometimes a mistake is induced by vague, cryptic, hidden, or ambiguous wording on the VB side.
It's not always immediately clear by definition, but afterwards it makes complete sense.

For example, Gremmy's article on IDE bugs/quirks, originally included a bug, that actually was really an unpredictable quirk for the talented developer.
I pointed out why it was not a bug:
The quirk(not bug), was that the Find/Replace window would not search for text if it was in closed Regions.

The unpredicted twist, was that you have to simply open up the "Find options", and choose "search hidden text".
In this case it's a hidden option(+), that is also vague because the option is titled "Search hidden text", and not "Search Regions", or something more appropriate.


A newbie should know that the immutability of the string data type is by designCORRECT.
I never said that the design itself is a quirk.
This is another misunderstanding.
It's just quirky to use, if you don't read up first, and fully understand the meaning of the definition. Newbs are expected to be doing that.

I guess even though people are experienced and know the facts we still need to explain small bits at times.
I'm glad you decided to explain what you really meant by performance.
You've got a pretty good understanding of the theory.
However, in practice Builder is still faster with a single, or just a few manipulations.
This contradicts what is written in most places, or at least the spirit of the words, but in my testing Builder is faster everytime for manipulations.
The proportion varies throughout the range, but is never slower.
Perhaps some machines, may not contradict this implication.

A real experienced developer does not code outside of his/her means, and always tests things first.
That notion is correct.
You are right though, that far to many developers think they are experts, and so that notion of over-confidence can cause problems.

Oblio
March 26th, 2009, 10:21 AM
You made this personal:
"Common now, are you really going to act like the suggestion to move the thread, is purely objective."

And I see where you called me a liar has been removed.

I have seen and answered many posts in many forums that went something like:

SUBJ: Problem With String
The string doesn't change when I did this

Dim s As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
s.Remove(0, 6)

'the normal answer for this is
s = s.Remove(0, 6)



I have seen it answered many ways, by many different people(including me), with discussions of immutability and stringbuilder. But this is the very first time I have ever heard it called a "quirk".

As far as speed differences, we all agree. Here is one test from my code timer.

Dim s As String = "abc"
Dim sb As New System.Text.StringBuilder
Dim retval As String
Private Function TestCase1() As Boolean 'One
'Test One Code Here
retval = ""
For x As Integer = 1 To 10
retval &= s
Next
'end test code
Return True
End Function
Private Function TestCase2() As Boolean 'Two
'Test Two Code Here
sb.Length = 0
For x As Integer = 1 To 10
sb.Append(s)
Next
retval = sb.ToString
'end test code
Return True
End Function


Results

03/26/09 10:19:34.657 CPU - 1.794GHz
x86 Family 6 Model 13 Stepping 6 Address width - 32
One - Concatenation
Two - StringBuilder
Outer Loops(OL)=7 Inner Loops=262,144 (ea. 1,835,008)
( times in ticks. 1 ms. = 10,000 ticks )
>> Two faster, 10.6788 ticks/loop
Ticks / Loop
0.0346 14.3088 3.6300 10.6788
OL Base One Two One - Two
1 8,987 3,078,209 949,328 2,128,881
2 8,998 3,111,321 947,723 2,163,598
3 8,960 5,077,462 953,127 4,124,335
4 8,988 3,129,498 950,599 2,178,899
5 9,665 3,113,121 956,045 2,157,076
6 8,982 5,629,046 950,436 4,678,610
7 9,001 3,118,117 953,758 2,164,359

Average
9,083 3,750,967 951,573 2,799,394
Variance
56,606.3 1,048,870,058,189.0 7,041,699.3
Standard Deviation
237.9 1,024,143.6 2,653.6
03/26/09 10:19:43.941


You should take your original post and post it at VBForums.