Use of Mid Statement in VB.Net

  • Thread starter Thread starter Harry Strybos
  • Start date Start date
Tom Shelton said:
Which of course I know. I spent a few years as a vb programmer myself :)


It can - but not in the way I was using it. The constructor I used set
the
max capcity, so the internal buffer can not grow beyond that. I also set
the
intial capacity so that the buffer is pre-allocated. Basically, the
buffer is
a fixed size - and will never grow or shrink... Basically avoiding a ton
of
memory allocations and string creation. In fact, the same buffer is used
in
every iteration of both .net algorithms. Setting the length = 0 basically
resets the internal pointer back to the begining of the buffer...



No, it was about if there was a way to accomplish the same task as the mid
statement that was faster. The answer is - yes.

I think most of us are aware of the fact that the vb.net mid is slower
then
the vb6 mid. But, any experienced .net developer is not going to bother
with
mid or strings in general for this kind of work. They are going to use a
StringBuilder - which is specifically designed for this kind of problem.

Well Tom, without getting drawn into the cynical "any experienced .net
developer is not going to bother", let me ask you how you would use the
StringBuilder to replace n characters at position x with some other
characters. eg I have a string "11111111111111111111111111" and I want to
replace "111" starting at position 6 with "222". You can't use the Replace
method.

Tom, I am dealing with bank files that have fixed length fields in a fixed
length string containing some filler fields that are left blank for bank use
or return of data. I also have to parse these rows at a later date to
extract various fields. Seems the Mid Function/Statement is well suited for
this task, although I do appreciate the speed advantages of the
StringBuilder class. Given that I typically would be building just 3-4k of
rows, the speed difference is marginal. I was, however, interested in
whether there was a more efficient method and your suggestions, (adding that
I use the StingBuilder class regularly) were most helpful, though not
exactly what I need.

I did reply to Armin Zingler and added some alternate code. Sadly, I have
not had a chance to test it for speed.
 
Michael D. Ober said:
It's unfortunate that MS didn't add a mid$() method statement to the
StringBuilder class. The insert methods actually extend the length of the
string and don't replace/overwrite the string contents. There are many,
many uses for the Basic MID$(<string>, <offset>, <length>) =
<insertstring> group of statements that have been part of the BASIC
language since the early days of BASIC and a well implemented version can
be extremely fast.

Mike Ober.
Hi Mike. Thank you for this and your other reply. You illuminate precisely
the point I was trying to make. I have replied to Tom Shelton with some
examples of usage I/we require.
 
Well Tom, without getting drawn into the cynical "any experienced .net
developer is not going to bother", let me ask you how you would use the
StringBuilder to replace n characters at position x with some other
characters. eg I have a string "11111111111111111111111111" and I want to
replace "111" starting at position 6 with "222". You can't use the Replace
method.

My statement was really ment were speed was critical. If, I was dealing with
a few strings, then probably I would use mid. But, to be honest, in your case
- I would use a stringbuilder. Your requirements are trivial to accomplish -
and you can easily encapsulate these methods in an extension method to
stringbuilder.
Tom, I am dealing with bank files that have fixed length fields in a fixed
length string containing some filler fields that are left blank for bank use
or return of data. I also have to parse these rows at a later date to
extract various fields. Seems the Mid Function/Statement is well suited for
this task, although I do appreciate the speed advantages of the
StringBuilder class. Given that I typically would be building just 3-4k of
rows, the speed difference is marginal. I was, however, interested in
whether there was a more efficient method and your suggestions, (adding that
I use the StingBuilder class regularly) were most helpful, though not
exactly what I need.

In what way? I created a fixed size buffer, if you are going to skip fields,
etc - it's a trivial matter to alter the code to preinit the buffer with
spaces.... it would slow it down a bit - but, it would be an almost
unnoticeable amount...


Option Strict On
Option Explicit On
Option Infer Off

Imports System
Imports System.Text
Imports System.Runtime.CompilerServices

Module Module1

Private Const RecordLength As Integer = 120

Sub Main()
Dim buffer As New StringBuilder(RecordLength, RecordLength)
buffer.InitBuffer(RecordLength, "*"c)
buffer.Mid(10, 4, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")
Console.WriteLine(buffer.ToString())
End Sub

<Extension()> _
Sub InitBuffer(ByVal buffer As StringBuilder, ByVal recordLength As Integer, ByVal filler As Char)
buffer.Length = 0
buffer.Length = recordLength
For i As Integer = 0 To buffer.Length - 1
buffer(i) = filler
Next
End Sub

<Extension()> _
Sub Mid(ByVal buffer As StringBuilder, ByVal start As Integer, ByVal length As Integer, ByVal value As String)
Dim j As Integer = start - 1 ' make it one based...
For i As Integer = 0 To length - 1
If i < value.Length Then
buffer(j) = value(i)
j += 1
Else
Exit Sub
End If
Next
End Sub
End Module

Seriously, once you have the routines written, you just use them in all your
projects... Obviously, you would want to add error handlign ect :)
I did reply to Armin Zingler and added some alternate code. Sadly, I have
not had a chance to test it for speed.

I haven't looked at that.
 
Tom Shelton said:
My statement was really ment were speed was critical. If, I was dealing
with
a few strings, then probably I would use mid. But, to be honest, in your
case
- I would use a stringbuilder. Your requirements are trivial to
accomplish -
and you can easily encapsulate these methods in an extension method to
stringbuilder.


In what way? I created a fixed size buffer, if you are going to skip
fields,
etc - it's a trivial matter to alter the code to preinit the buffer with
spaces.... it would slow it down a bit - but, it would be an almost
unnoticeable amount...


Option Strict On
Option Explicit On
Option Infer Off

Imports System
Imports System.Text
Imports System.Runtime.CompilerServices

Module Module1

Private Const RecordLength As Integer = 120

Sub Main()
Dim buffer As New StringBuilder(RecordLength, RecordLength)
buffer.InitBuffer(RecordLength, "*"c)
buffer.Mid(10, 4, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")
Console.WriteLine(buffer.ToString())
End Sub

<Extension()> _
Sub InitBuffer(ByVal buffer As StringBuilder, ByVal recordLength As
Integer, ByVal filler As Char)
buffer.Length = 0
buffer.Length = recordLength
For i As Integer = 0 To buffer.Length - 1
buffer(i) = filler
Next
End Sub

<Extension()> _
Sub Mid(ByVal buffer As StringBuilder, ByVal start As Integer, ByVal
length As Integer, ByVal value As String)
Dim j As Integer = start - 1 ' make it one based...
For i As Integer = 0 To length - 1
If i < value.Length Then
buffer(j) = value(i)
j += 1
Else
Exit Sub
End If
Next
End Sub
End Module

Seriously, once you have the routines written, you just use them in all
your
projects... Obviously, you would want to add error handlign ect :)


I haven't looked at that.

Thanks Tom, now we are on the same page. The answer was the "<Extension()>"
attribute, something I was not aware of. This will give me a way to use
StringBuilder that I did not know was possible. Always something new to
learn in .Net. Thanks again, Tom, you are the man :)
 
Harry said:
Hi Armin. Just to clarify what I am doing. The files I build (bank
transaction files) must contain n characters per row (eg 120) with each row
comprising of n fixed length fields.

Generally I can just roll along using a pointer to my position in the row
and effectively append field after field. There are time however when I need
to skip some optional fields and then write data further along. The reverse
of this is that I also need to parse files of this type extracting field
values at various positions.

The Mid Function and Statement serve this purpose admirably, however, I have
always been curious as to whether there was a more efficient method. I am
aware that both VB6 and VB.Net have the Mid Function/Statement and I was
also aware that the VB.Net Mid was quite a bit slower.

Tom Shelton's figures tell me that this is probably insignificant as the
bank files I produce typically would only have 3-4k rows. As I mentioned,
the whole thing just becomes academic when we can see the insignificant
differences that the test results produce in the 3-4k range.

The Byte array idea was to simply try something else. Here is the code
(sorry, have to include the whole class). I have not yet tested this:

I guess you don't have a question but it's just to let us know the
current state of affairs (and to answer my question). Well, the only
thing (if I may say "only" in this context meaning that I didn't
completely check the whole class ;-) ) I see is that you're using
ASCII encoding. But that may be fine with the bank files you're
writing (as you probably know, ASCII is 7 bits only). Otherwise it's
only a time consuming conversion.

The other thing is that you may want to use Array.Copy which can be much faster
than a For-Next loop (I've experienced the same a short time ago when
speed was the main issue).

Well, if the class works fine for you, use it. Still knowing that it
was more an academic question, I still think the Stringbuilder is
very quick as long as you reuse the same instance with an
appropriate capacity, even though you'd have to immitate the
behavior of replacing parts of it's content. An array of characters,
as it's already been mentioned may be a good alternative, too. Maybe
instead of an array of bytes in your own class. Just some thoughts. So, I
actually can't add anything really new to my first post. :-)

The only valuable contribution from Mike in this thread was the (unanswered)
question _why_ a String is immutable. I'd be interested in an answer, too.
Because it changes the "identity" of the String? I don't know. Just guessing.
 
Harry Strybos said:
Oops... Dim buffer as New String(" "c, 120)
Hi All

Thanks again for all your time. We are all people interested in programming.
My initial thrust is against just a few participating in this group.

Whatever the flavour of the language you prefer, I think that we do not need
to use this dignified pursuit, or this group, to voice hatred of each
other. If you like to use VB.Net, make comments or help each other in this
paradigm. If you use VB6 (or previous), then stick to your own group.
Puerile insult never makes a valid argument!

I am appalled by some of the sometimes racist and otherwise unkind remarks
made in the alleged interest of answering the question I posed.

We ostensibly pose as intellectual people in this group, yet some "visitors"
expose the most base and negative attributes of humanity. This type of
negative response is best left to the Nazi party, and others of a similar
non-intellectual and primitive ilk.

For those that don't want to be part of VB.Net, who is forcing you? None of
us here have any influence on the decisions that Microsoft make, so why
blame us? Go abck to your own group!

As for me, I was a "dyed in the wool" VB6 afficianado, and initially berated
Microsoft for the change in the language paradigm that VB.Net introduced. In
reality, most of this was about my fear of losing my intellectual investment
or fear of having to learn something new.

However, simple perserverance quickly showed that the change to the .Net
paradigm was a very rewarding move indeed. The power of .Net is
overwhelming. Am I a Microsoft evangelist...hell no! Do I think Microsoft
makes mistakes, hell yes!. I do say, however, that if you are a VB6 user,
try an unbaised approach to .Net...it is well worth the effort.

For the few that are against the .Net paradigm and continue to vocalise
negatively in this group, all I can say is ....get over it! You cannot give
credence to your arguments by simply debasing others, or presenting puerile
or irrelevent arguments. At the end of the day, nobody here cares if some
small aspect of VB6 was faster than the equivalent in VB.Net. At the end of
the day, VB.Net is hugely more powerful and easy to use than the old, and
unsupported, com based language.

The world is a changing place and sometimes the systems that we rely upon
become outdated. Will VB.Net become outdated?, probably. Your intellectual
worth is about adapting to change, not pursuing your perception of what
should be. History shows us that this type of thinking is usually very
destructive.

There are many brilliant people in this group(as there are in the VB
"classic" group) that selflessly give their time to help others. If you want
to disagree, no problems, however, I hope my dissertation above will have
some positive effect on your input.

Cheers

Harry Strybos
 
If you use VB6 (or previous), then
stick to your own group.

And what about people who use VB.Net? What do you think they should do?

Personally I believe that people should be free to use whatever groups they
wish to use, as long as they are genuinely interested in the subject and are
there either to ask questions or to provide real and genuine help others who
have done so, and as long as they are not there specifically to cause
trouble in the way that the Clark/Scott/McCarthy troll does in the VB6
group. If the Clark/Scott/McCarthy troll was not deliberately causing
trouble in the VB6 group then people would not be tempted to follow it here.

Mike
 
There are many brilliant people in this group(as there
are in the VB
"classic" group) that selflessly give their time to help
others. If you want
to disagree, no problems, however, I hope my
dissertation above will have
some positive effect on your input.

Your attempt to take the high road is nice,
if a bit didactic. (Stubborness and argumentativeness
don't have a favorite programming language, after all. :)
But one has to wonder why you didn't act 3 days ago.
Much of the arguing came out of the fact that your
original post was ambiguous:

"The beauty of the old VB6 Mid statement (which is
available in VB.Net)"

The statement doesn't make much sense as-is,
since you were asking for a .Net alternative to Mid.

Yet you sat by silently for two days while everyone
argued about it. That very ambiguity fanned the
flames. You yourself could have cleared things up
(and prevented people from wasting time trying to
clarify your question) at the beginning.
 
The only valuable contribution from Mike in this thread was the (unanswered)
question _why_ a String is immutable. I'd be interested in an answer, too.
Because it changes the "identity" of the String? I don't know. Just guessing.

There are lots of reasons that strings are immutable in .NET - but the main
reasons are thread saftey and performance. By not allowing strings to be
altered, means you can more safely share them across multiple threads.

Also, because strings are immutable, they are able to be pooled - so, that all
string litterals refere to the same string. So, it allows for more efficient
use of memory resources... I don't know if .NET goes to the same level as
Java on this, but in the JVM I've read that it goes so far as to share
substrings even. In other words, when you call substring on a string it
returns an object that points into a new location in the old strings buffer -
so, no copies are made and it makes it a very cheap operation.

Further, because strings are immutable, they behave more like a value type
then a reference type - and ByVal/ByRef symantics are preserved. Which is
nice, otherwise you would need to be copying your strings all over the place
to avoid unintended alterations. Basically, for typical usage of a string,
immutability actually is advantageous.

Where immutability is a problem is when you must dynamically build large
strings or do a lot of alteration to the strings. Which is why StringBuilder
was introduced - to accomodate this usage.

The one place VB.NET blurs the distinction between immutability and mutability
of strings is with interop calls. VB.NET actually allows you to use a string
as a output buffer of an API call I suppose they do this to maintain
compatability with VB.CLASSIC, but I think it is a mistake - and it is why I
actively discourage the use of string as an output buffer for API calls.
StringBuilder is much more appropriate for this purpose - and in fact, is the
only way this works in languages such as C#, since it's marshaler does respect
the immutablity of strings and you will not get a result back.
 
We ostensibly pose as intellectual people in this group, yet
some "visitors" expose the most base and negative attributes
of humanity. This type of negative response is best left to the
Nazi party, and others of a similar non-intellectual and
primitive ilk.

I find that remark rather strange, coming as it does from someone such as
yourself who lives in Australia, a country whose population consists mostly
of the recent descendents of burglars, thieves, muggers, rapists and various
other miscreants who were transported there in order to remove them from
civilized society and who to this day still behave very much like the Nazi
party in their dealings with the indigenous population, who are the real
owners of Australia.

Mike
 
Armin Zingler said:
I guess you don't have a question but it's just to let us know the
current state of affairs (and to answer my question). Well, the only
thing (if I may say "only" in this context meaning that I didn't
completely check the whole class ;-) ) I see is that you're using
ASCII encoding. But that may be fine with the bank files you're
writing (as you probably know, ASCII is 7 bits only). Otherwise it's
only a time consuming conversion.

The other thing is that you may want to use Array.Copy which can be much
faster
than a For-Next loop (I've experienced the same a short time ago when
speed was the main issue).

Well, if the class works fine for you, use it. Still knowing that it
was more an academic question, I still think the Stringbuilder is
very quick as long as you reuse the same instance with an
appropriate capacity, even though you'd have to immitate the
behavior of replacing parts of it's content. An array of characters,
as it's already been mentioned may be a good alternative, too. Maybe
instead of an array of bytes in your own class. Just some thoughts. So, I
actually can't add anything really new to my first post. :-)

The only valuable contribution from Mike in this thread was the
(unanswered)
question _why_ a String is immutable. I'd be interested in an answer, too.
Because it changes the "identity" of the String? I don't know. Just
guessing.
Thanks Armin. Tom Shelton provided some excellent help with the
"<Extension()>" attribute so you can basically roll your own Mid Statement
into the StringBuilder class. Nice idea!
 
Harry said:
Thanks Armin. Tom Shelton provided some excellent help with the
"<Extension()>" attribute so you can basically roll your own Mid Statement
into the StringBuilder class. Nice idea!

You mean that Extension attribute I've already mentioned in my first reply? ;-)
 
Mike Williams said:
And what about people who use VB.Net? What do you think they should do?

Personally I believe that people should be free to use whatever groups they
wish to use, as long as they are genuinely interested in the subject and are
there either to ask questions or to provide real and genuine help others who
have done so, and as long as they are not there specifically to cause
trouble in the way that the Clark/Scott/McCarthy troll does in the VB6
group. If the Clark/Scott/McCarthy troll was not deliberately causing
trouble in the VB6 group then people would not be tempted to follow it here.

Debating or insulting trolls, or engaging in troll-like behavior does
NOT stop trolls. If you can track them back to their ISP you *might*
be able to get their account canceled but that's unlikely and would
probably only result in them switching ISPs.

It takes a while and is not always successful, but ignoring trolls is
really the only semi-effective way of dealing with them.
 
| Debating or insulting trolls, or engaging in troll-like behavior does
| NOT stop trolls. If you can track them back to their ISP you *might*
| be able to get their account canceled but that's unlikely and would
| probably only result in them switching ISPs.
|
| It takes a while and is not always successful, but ignoring trolls is
| really the only semi-effective way of dealing with them.

Or, you could take the Bill McCarthy route, gather as much info as one
thinks they knows and post it all on some pathetic troll site. All that
really accomplishes is reinforce Mike's original statement about the kind of
people who live in Australia really are. <eg>
 
It takes a while and is not always successful, but ignoring trolls
is really the only semi-effective way of dealing with them.

Actually you may me right there, JB. If eveyone else here and on the VB6
group ignore the Alex Clark / Scott M / Bill McCarthy triple headed troll
then I shall ignore it as well.

Mike
 
Back
Top