Use of Mid Statement in VB.Net

  • Thread starter Thread starter Harry Strybos
  • Start date Start date
Isn't it the basic language keywords that make
a language be recognizable as such?

Not in the case of VB.Net. In that case the BASIC language keywords are just
flavourings sprinkled over a completely different product in order to
disguise it and in order to pretend that it is something which it is not.
It's a marketing gimmick Adolf.

Mike
 
So, what do we learn - the vb.net mid statement
is about ~.5x the speed of the VB6 mid statement.

Your code is timing not just the Mid statement but also the creation of the
test string. You will find that the speed of VB6 Mid is shown to be much
greater if you correct that problem. Also, the VB6 Mid statement might be
not much more than four times as fast as VB.Net Mid statement when used on
extremely small strings such as the string used in your test (especially
when the timing is currupted by including other string functions in the same
test, as you have done), but it is very very much faster than VB.Net when
used on longer strings, up to hundreds of times faster on very long strings.

Mike
 
Your code is timing not just the Mid statement but also the creation of the
test string.

Yes. But then, how do you suggest I get the new buffer each time? I guess I
shouldn't be saying the mid statement it self, but the algorithm using VB's
built in string handling...
You will find that the speed of VB6 Mid is shown to be much
greater if you correct that problem. Also, the VB6 Mid statement might be
not much more than four times as fast as VB.Net Mid statement when used on
extremely small strings such as the string used in your test (especially
when the timing is currupted by including other string functions in the same
test, as you have done), but it is very very much faster than VB.Net when
used on longer strings, up to hundreds of times faster on very long strings.

Have you tested that? Looking at the implmentation of the VB.NET mid
statement, I can't see how it could be hundreds of times faster.

Of course, that's neither here or there - using the native .net stringbuilder
is going way faster then using the vb.net or vb6 mid. And that was really the
point of the whole exercise.
 
Yes. But then, how do you suggest I get the new buffer each time? I guess I
shouldn't be saying the mid statement it self, but the algorithm using VB's
built in string handling...


Have you tested that? Looking at the implmentation of the VB.NET mid
statement, I can't see how it could be hundreds of times faster.

Meant slower :)
 
Have you tested that?

Yes, I have tested it. The longer the target string the greater the speed
difference.
Looking at the implmentation of the VB.NET mid
statement, I can't see how it could be hundreds of
times faster

The VB.Net Mid statement creates a new string whereas the VB6 Mid statement
does not, with VB6 Mid inserting the desired substring directly into the
already existing target string. That is what accounts for the significant
speed difference even on very short target strings, and the massive speed
difference on very large target strings. By the way, just out of interest, I
notice that you use Mid instead of Mid$ in your VB6 tests. In VB6 this does
not in fact make any difference with the Mid statement, but it makes a big
difference with the Mid function and with other native VB6 string functions,
where the $ variant (Mid$, Left$, Right$ etc rather than Mid, Left, Right
etc) is faster.
Of course, that's neither here or there - using the native .net
stringbuilder is going way faster then using the vb.net or
vb6 mid. And that was really the point of the whole exercise.

It depends what you are testing. The VB6 Mid statement cannot in itself
extend the length of the target string, and I think that is also the case
with the VB.Net Mid statement, whereas the VB.Net StringBuilder almost
certainly can. I very much doubt that VB.Net StringBuilder will be faster
than VB6 Mid statement when performing the task that both of them can
perform. As you are aware, I don't code in VB.Net myself and so I don't know
how the VB.Net StringBuilder performs, although I imagine that for general
string handling it will peform at much the same speed as the non native
string building functions that have been written in VB6, and of course very
much better than the native VB6 methods of building strings from substrings
when the length of the target string is being changed, because the native
VB6 concatenation methods create a new string under such circumstances. In
fact I imagine that the VB.Net StringBuilder will perform at least equally
as fast as the various string building methods that are available in VB6 if
you write them yourself instead of simply using the native built in
functions. But of course this thread was all about the Mid statement, and it
is clear that the VB6 Mid statement is very much faster than the VB.Net Mid
statement.

Mike
 
Yes, I have tested it. The longer the target string the greater the speed
difference.


The VB.Net Mid statement creates a new string whereas the VB6 Mid statement
does not, with VB6 Mid inserting the desired substring directly into the
already existing target string. That is what accounts for the significant
speed difference even on very short target strings, and the massive speed
difference on very large target strings. By the way, just out of interest, I
notice that you use Mid instead of Mid$ in your VB6 tests. In VB6 this does
not in fact make any difference with the Mid statement, but it makes a big
difference with the Mid function and with other native VB6 string functions,
where the $ variant (Mid$, Left$, Right$ etc rather than Mid, Left, Right
etc) is faster.

Which of course I know. I spent a few years as a vb programmer myself :)
It depends what you are testing. The VB6 Mid statement cannot in itself
extend the length of the target string, and I think that is also the case
with the VB.Net Mid statement, whereas the VB.Net StringBuilder almost
certainly can.

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...

In
fact I imagine that the VB.Net StringBuilder will perform at least equally
as fast as the various string building methods that are available in VB6 if
you write them yourself instead of simply using the native built in
functions. But of course this thread was all about the Mid statement, and it
is clear that the VB6 Mid statement is very much faster than the VB.Net Mid
statement.

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.
 
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.

As with most things, the devil is in the detail and what you omit is often
more important than what you say. The answer is only a definite "Yes" if you
mean "faster than the VB.Net Mid statement", not if you mean faster than the
VB6 Mid statement.
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.

Well I never suggested they would, any more than I would suggest an
experienced VB6 developer would use the native VB6 concatenation method of
building strings when speed is of the essence, when they can instead write
their own very fast string builder class, or use one of the excellent freely
available ready written VB6 string builder classes. As I have always said,
it's horses for courses.
Which of course I know [in answer to a paragraph containing
statements about two different subjects]

Again, what you omit is often more important than what you actually say,
which is what I have been trying to point out to Adolf Zingler. Your
statement, "Which of course I know", is in response to a paragraph of mine
that was itself a response to your own statement when you said, "Looking at
the implementation of the VB.NET mid statement, I can't see how it could be
hundreds of times faster". That paragraph of mine (the one to which you have
just responded) was mainly concerned with a major detail of the difference
in implementation between the VB6 and VB.Net Mid statements, in order to
explain to you why the VB6 Mid statement was so much faster than the VB.Net
Mid statement, especially on long strings. It also contained a "by the way"
reference to the difference between the speed of VB6 string functions
depending on whether you use the $ version or not. Your statement "Which of
course I know" would probably be taken by other readers as indicating that
you knew about the entire content of the paragraph of mine to which you were
responding, whereas in fact it would appear that either you did not know
about the fact that VB.Net Mid creates a new string, or that you knew about
it but could not see how it might produce the vast speed differences that I
had mentioned when dealing with very long strings, otherwise you would not
have previously made your statement, "Looking at the implementation of the
VB.NET mid statement, I can't see how it could be hundreds of times faster".
I'm sure you didn't intend your "Which of course I know" statement to
deliberately mislead other people, but I'm also sure you can see that it
might do so, hence my rather verbose clarification.

I take it therefore that your comment "Which of course I know" refers only
to my "by the way" comments regarding the $ business and that it does not
apply to the main content of that paragraph regarding the vast difference in
speed, especially on very long strings, between the VB6 Mid statement and
the VB.Net Mid statement, because if you did actually already know the
details in respect of the two differently implemented Mid statements, and if
you understood the full implications of it, then you would not have said
that you could not see how it could make such a big difference in speed on
very long strings.

Personally I think this thread has been done to death by now, but if you
wish to do so then we can of course go on arguing for ages about such
trivial things, each attempting to score points off the other, as we have
seen before in the thread about graphics when I showed you how very fast VB6
can be at counting the number of unique colours used in a .bmp file, very
much faster than any VB.Net equivalent that you've so far come up with. Is
that what you want? A long drawn out argument? If so then be my guest.
Perhaps we can invite the multi headed Clark/Scot/McCarthy troll and turn it
into a party :-)
I spent a few years as a vb
programmer myself :)

I notice that you've used the term "vb" to specifically indicate VB6,
apparently in acknowledgement that VB.Net is not really VB at all. I'm glad
to see that you agree with me on that point ;-)

Mike
 
Mike said:
Not in the case of VB.Net.

You are wrong again. It's still If-Then-Else-ElseIf-EndIf, For-Next, Do-Loop, Function-End Function,
Sub-End Sub, Select Case-Case-End Select. Or are you saying they don't exit in both languages?
Are these C keywords? No. Therefore they make VB.Net another version of VB. You can even write
"End" to quit the application. And guess what else? Yes, even the Mid statement still works. You
still use Or, And, =, <, etc operators. You don't use "==" for comparisions, do you? You can
seperate statements on the same line with the ":". Declare functions using the Declare statement. I
could mention a lot more, but I guess you have access to the documentation, too.
Everything is typcial VB.

Though you are not able to recgonize VB.Net as one version of VB.

The basic language keywords form a language family. You have decisisons, branches, functions,
function calls, etc in every language, but the differences are the keywords and semantics
used. Enhancements made create new versions. That's natural law but not a reason to exclude
a new version from the language family as long as the basic keywords stay the same. And they did.
The platform the language is based on is not a criterion, otherwise C# and VB.Net would have to be
called the same language.

It's a marketing gimmick Adolf.

You do me a favor showing us your real face.
 
Mike said:
"Harry only mentioned that the Mid statement was
already there in VB6 and he is now working with VB.Net, and he needs a
solution for VB.Net". That is not correct Adolf. That is not the only thing
he said in his original post.

I assumed you were aware of the context of the sentence. The context is the
posting I was referring to, containing a lengthy VB6 essay, and my following
sentences. Here they are again:


"Harry only mentioned that the Mid statement was already there in VB6.
He is now working with VB.Net, and he needs a solution for VB.Net.
Therefore all my statements are related to VB.Net and all examples
are written for VB.Net

If you're trying to apply my statements to VB6 or trying to execute my
code in VB6, it's really your own problem."


In this context the sentence means what I've already explained.
 
Armin Zingler said:
You are wrong again. It's still If-Then-Else-ElseIf-EndIf, For-Next,
Do-Loop, Function-End Function,Sub-End Sub, Select
Case-Case-End Select. Or are you saying they don't exit in
both languages?

No, Adolf. I'm saying that they are the flavourings with which the new and
completely different product has been sprinkled in order to disguise its
true nature.

Mike
 
I assumed you were aware of the context of the sentence. The
context is the posting I was referring to, containing a lengthy
VB6 essay, and my following sentences. Here they are again:
"Harry only mentioned that the Mid statement was already
there in VB6."

No, that is not the only thing he mentioned. You are wrong, Adolf. He
mentioned other things as well, things which you have omitted, including a
statement to the effect that he knows that Mid is also available in VB.Net.
He then asked for something fast in VB.Net, clearly indicating that he also
knew that Mid in VB.Net is very much slower than Mid in VB6. Why do you seem
to have a problem with that?
He is now working with VB.Net, and he needs a solution for
VB.Net. Therefore all my statements are related to VB.Net
and all examples are written for VB.Net

That's fine. I have no problems with that, and I never said that I have.
If you're trying to apply my statements to VB6 or trying to
execute my code in VB6 . . .

No. I never said that either, and neither did I try to run your VB.Net code
in VB6. You are making things up again, Adolf.
. . . it's really your own problem

No. You are the problem, Adolf. You are turning into as much of a troll as
the three headed Clark/Scot/McCarthy monster. If you carry on like this you
will soon qualify to be its fourth head.

Mike
 
Mike said:
No, that is not the only thing he mentioned.

You are still ignoring the context. You are still ignoring explanations.
How often do you think I will repeat them? :-)
He
mentioned other things as well, things which you have omitted,

It is wrong that I have omitted them. The opposite is the case. I have
mentioned them several times but you are ignoring it.
including a
statement to the effect that he knows that Mid is also available in VB.Net.

As you can take from my previous postings I know this. You are ignoring it.
He then asked for something fast in VB.Net,

You made a correct statement. Congratulations!
clearly indicating that he also
knew that Mid in VB.Net is very much slower than Mid in VB6.

I've never said the opposite.
Why do you seem
to have a problem with that?

I have no problem at all.
That's fine. I have no problems with that, and I never said that I have.

You did not notice that I quoted my reply to mayayana. It was
not a reply to you. So it's completely out of the context again.
No. I never said that either, and neither did I try to run your VB.Net code
in VB6. You are making things up again, Adolf.

You did not notice that I quoted my reply to mayayana. It was
not a reply to you. So it's completely out of the context again.

No. You are the problem, Adolf. You are turning into as much of a troll

By patiently making you aware of the lies you are telling, I don't make
a troll of myself.

as
the three headed Clark/Scot/McCarthy monster. If you carry on like this you
will soon qualify to be its fourth head.

Well, as you get caught up in contradictions more and more and start becoming
the spawn of absurdity, my own head says that it's time to stop the discussion
in order to protect you from further blindfolded statements and actions, and,
in first place, to spare the participants in this group further boring discussions.
 
You are still ignoring the context. You are still ignoring
explanations.

No I am not. You are ignoring my explanations.
How often do you think I will repeat them? :-)

For ever, I would imagine, Adolf. After all, you are a troll.

Mike
 
mayayana said:
Actually, VB Mid$ is extremely fast. It seems
to be treating the string as an integer
array... which it is... which allows characters
to be replaced without creating a new string.
(Assuming Mid$ is being used on a string
buffer of sufficient length.

In .NET strings are immutable, whether Mid translates string chars into
integers or not, to create a different string value than you started with
requires a new string object to be created.

-Scott
 
Harry,

The Mid is not a VB6 statement, it is a Visual Basic statement which is in
all versions from VB including VBS and VBA.

To declare Mid as something from VB6 puts this version in my idea in a
complete wrong context. VB6 is just a version from Visual Basic, however it
can not handle Net.

All "language" elements from Visual basic are still in Visual Basic language
version 9 and will be in language version 10.

You should not confuse Net with Visual Basic.

However in Net is the String not very inefficient, which has in fact nothing
to do with Visual Basic.

Cor
 
It's not clear from your original post, but the Mid statement is still
I think he knows it because he wrote "the old VB6 Mid statement (which
is available in VB.Net)".
No because it is not an old VB6 statement, it is an old Basic statement
which is like David wrote still in Visual Basic.
 
The Mid is not a VB6 statement, it is a Visual Basic
statement which is in
all versions from VB including VBS and VBA.

Unfortunately it's missing in VBScript. I wish
it were there, but VBS only has the Mid function.
 
The Mid is not a VB6 statement

Yes it is.
It is a Visual Basic statement which is in all versions from VB including
VBS and VBA.

And it is that too.

However, its implementation in VB.Net is totally different to its
implementation in VB6, making the VB.Net Mid statement considerably slower.
You should not confuse Net with Visual Basic.

He didn't. In any case, you should be saying exactly that to the dotnet
trolls who from time to time infest the Classic VB newgroup and who
deliberately confuse the two in an attempt to cause trouble, a group of
trolls who you are yourself a member of.
However in Net is the String not very inefficient

It's not Net strings in themselves that are inefficient, although the VB.Net
Mid statement certainly is.
You should not confuse Net with Visual Basic.

Agreed. You're quite right there. Net has nothing to do with Visual Basic
;-)

Mike
 
Armin Zingler said:
No need to apologize. You're welcome! Only very few people here have
their,
let's say "special" opinion about VB.Net - which is acceptable - but
unfortunatelly that is often expressed in unfounded allegations, twisting
one's words or laying into someone the nasty way.

May I ask what you're trying with the Byte array? I have doubts because
it seems to imply (time consuming) character en/decoding.

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:

Public Class StringBuffer

Implements IDisposable

#Region " Variables "

Private Const M As String = "StringBuffer-"
Private Const SEP As String = "-"

'----------------
'internal storage
'----------------
Private _buffer As Byte()

Private _encoding As New System.Text.ASCIIEncoding()

'----------------------------------
'points to current postion in array
'----------------------------------
Private _pointer As Integer
#End Region

#Region " Properties "

Public ReadOnly Property Pointer() As Integer
Get
Return _pointer
End Get
End Property
#End Region

#Region " Methods "

''' <summary>
''' Write text from current pointer position
''' </summary>
''' <param name="sText"></param>
''' <returns>Boolean</returns>
''' <remarks>pointer increments after each write</remarks>
Public Function Write(ByVal sText As String) As Boolean

Try

Dim temp() As Byte = _encoding.GetBytes(sText)

For i As Integer = 0 To (temp.Length - 1)

_buffer(_pointer) = temp(i)

'--------------------------------
'we need to increment our pointer
'--------------------------------
_pointer += 1

Next

Return True

Catch ex As Exception
Throw New Exception(M &
System.Reflection.MethodInfo.GetCurrentMethod.Name & SEP & ex.Message)
End Try

End Function
''' <summary>
''' Write text from nominated start position
''' </summary>
''' <param name="StartPos"></param>
''' <param name="sText"></param>
''' <returns>Boolean</returns>
''' <remarks></remarks>
Public Function Write(ByVal StartPos As Integer, ByVal sText As String)
As Boolean

Try

Dim temp() As Byte = _encoding.GetBytes(sText)

For i As Integer = 0 To (temp.Length - 1)

_buffer(StartPos + i) = temp(i)

Next

Return True

Catch ex As Exception
Throw New Exception(M &
System.Reflection.MethodInfo.GetCurrentMethod.Name & SEP & ex.Message)
End Try

End Function

''' <summary>
''' Read n characters from nominated start position
''' </summary>
''' <param name="StartPos"></param>
''' <param name="nChars"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Function Read(ByVal StartPos As Integer, ByVal nChars As Integer)
As String

Try

Return _encoding.GetString(_buffer, StartPos, nChars)

Catch ex As Exception
Throw New Exception(M &
System.Reflection.MethodInfo.GetCurrentMethod.Name & SEP & ex.Message)
End Try

Return String.Empty

End Function

Public Overrides Function ToString() As String

Try

Return _encoding.GetString(_buffer)

Catch ex As Exception
Throw New Exception(M &
System.Reflection.MethodInfo.GetCurrentMethod.Name & SEP & ex.Message)
End Try

Return String.Empty

End Function
#End Region

#Region " IDisposable Support "
Private disposedValue As Boolean
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
_buffer = Nothing
_pointer = Nothing
_encoding = Nothing
End If
End If
Me.disposedValue = True
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region

#Region " Constructors "

Public Sub New(ByVal BufferLength As Integer)

ReDim _buffer(BufferLength - 1)

End Sub
Public Sub New(ByVal BufferLength As Integer, ByVal CharType As Char)

Dim temp As New String(CharType, BufferLength)

_buffer = _encoding.GetBytes(temp)

End Sub
Public Sub New(ByVal sBuffer As String)

_buffer = _encoding.GetBytes(sBuffer)

End Sub

#End Region

End Class
 
Back
Top