VB6 vs. VB.Net Speed

G

Guest

I migrated VB6 code to VB.Net and after building in the release mode and setting Optimizations to Remove integer overflow checks and Enable optimizations the exe runs at a miserably slow speed compared to VB6 exe.
Processing an 80k byte text file in VB6 takes less then a second.
The same code processs in VB.Net takes over a minute.
What am I overlooking?

The code is converting Un-typeable characters into typeable characters. It is called "Stretch" and increases the length of the file a bit . It is from an old Visual Basic book by John Craig.
I migrated it almost as is to VB.Net
Here is the code:
lA = (Len(msText))
sB = Space(lA + (lA + 2) \ 3) 'New Stretched length


For lI = 1 To lA

nC = (Asc(Mid(msText, lI, 1)))
lJ = lJ + 1
Mid(sB, lJ, 1) = Chr((nC And 63) + 59)

Select Case lI Mod 3
Case 1
nK = (nK Or ((nC \ 64) * 16))
Case 2
nK = (nK Or ((nC \ 64) * 4))
Case 0
nK = (nK Or (nC \ 64))
lJ = lJ + 1
Mid(sB, lJ, 1) = Chr(nK + 59)
nK = 0
End Select
Next lI
 
A

Armin Zingler

Richard506 said:
I migrated VB6 code to VB.Net and after building in the release mode
and setting Optimizations to Remove integer overflow checks and
Enable optimizations the exe runs at a miserably slow speed compared
to VB6 exe. Processing an 80k byte text file in VB6 takes less then a
second. The same code processs in VB.Net takes over a minute. What am
I overlooking?

The code is converting Un-typeable characters into typeable
characters. It is called "Stretch" and increases the length of the
file a bit . It is from an old Visual Basic book by John Craig. I
migrated it almost as is to VB.Net Here is the code:
lA = (Len(msText))
sB = Space(lA + (lA + 2) \ 3) 'New Stretched length


For lI = 1 To lA

nC = (Asc(Mid(msText, lI, 1)))
lJ = lJ + 1
Mid(sB, lJ, 1) = Chr((nC And 63) + 59)

Select Case lI Mod 3
Case 1
nK = (nK Or ((nC \ 64) * 16))
Case 2
nK = (nK Or ((nC \ 64) * 4))
Case 0
nK = (nK Or (nC \ 64))
lJ = lJ + 1
Mid(sB, lJ, 1) = Chr(nK + 59)
nK = 0
End Select
Next lI

I don't know if it explains everything, but one big difference might be the
different string usage. In VB6, you could exchange single chars in a string
by using the mid statement. Strings in VB.NET are "immutable", i.e. you can
_not_ exchange single chars or parts of the string. In VB.NET, the mid
statement creates a *new* string. Have a look at the
System.Text.Stringbuilder class. It might make it a lot faster.
 
D

David Ricker

Armin is correct. Using the StringBuilder vastly improves the time of this
code. I set up the following test and found it took an average of 671.875
milliseconds using the provided code, but only 15.625 milliseconds when
using a stringbuilder. Here is the code I used to test.

Sub Stretch(ByVal msText As String)
Dim tm As DateTime = Now
Dim lA, lI, nC, lJ, nK As Integer
Dim sB As String
lA = msText.Length
sB = Space(lA + (lA + 2) \ 3) 'New Stretched length
For lI = 1 To lA
nC = (Asc(Mid(msText, lI, 1)))
lJ = lJ + 1
Mid(sB, lJ, 1) = Chr((nC And 63) + 59)
Select Case lI Mod 3
Case 1
nK = (nK Or ((nC \ 64) * 16))
Case 2
nK = (nK Or ((nC \ 64) * 4))
Case 0
nK = (nK Or (nC \ 64))
lJ = lJ + 1
Mid(sB, lJ, 1) = Chr(nK + 59)
nK = 0
End Select
Next lI
Debug.WriteLine(Now.Subtract(tm).TotalMilliseconds)
End Sub
Sub Stretch2(ByVal msText As String)
Dim tm As DateTime = Now
Dim lA, lI, nC, lJ, nK As Integer
Dim sB As String
Dim strB As New System.Text.StringBuilder
lA = msText.Length
For lI = 1 To lA
nC = (Asc(Mid(msText, lI, 1)))
lJ = lJ + 1
strB.Append(Chr((nC And 63) + 59))
Select Case lI Mod 3
Case 1
nK = (nK Or ((nC \ 64) * 16))
Case 2
nK = (nK Or ((nC \ 64) * 4))
Case 0
nK = (nK Or (nC \ 64))
lJ = lJ + 1
strB.Append(Chr(nK + 59))
nK = 0
End Select
Next lI
sB = strB.ToString
Debug.WriteLine(Now.Subtract(tm).TotalMilliseconds)
End Sub

Private Sub btn_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btn.Click
Dim strb As New System.Text.StringBuilder
For i As Integer = 0 To 9999
strb.Append(Chr(CInt(Int((46 * Rnd()) + 50))))
Next
Stretch2(strb.ToString)
Stretch(strb.ToString)
End Sub
 
T

Tom Shelton

I migrated VB6 code to VB.Net and after building in the release mode and setting Optimizations to Remove integer overflow checks and Enable optimizations the exe runs at a miserably slow speed compared to VB6 exe.
Processing an 80k byte text file in VB6 takes less then a second.
The same code processs in VB.Net takes over a minute.
What am I overlooking?

The code is converting Un-typeable characters into typeable characters. It is called "Stretch" and increases the length of the file a bit . It is from an old Visual Basic book by John Craig.
I migrated it almost as is to VB.Net
Here is the code:
lA = (Len(msText))
sB = Space(lA + (lA + 2) \ 3) 'New Stretched length


For lI = 1 To lA

nC = (Asc(Mid(msText, lI, 1)))
lJ = lJ + 1
Mid(sB, lJ, 1) = Chr((nC And 63) + 59)

Select Case lI Mod 3
Case 1
nK = (nK Or ((nC \ 64) * 16))
Case 2
nK = (nK Or ((nC \ 64) * 4))
Case 0
nK = (nK Or (nC \ 64))
lJ = lJ + 1
Mid(sB, lJ, 1) = Chr(nK + 59)
nK = 0
End Select
Next lI

2 things... Don't use the VB.NET File I/O functions. Use the classes
defined in System.IO for reading the file. And the second thing, use a
System.Text.StringBuilder for your string operations. .NET strings are
immutable and the Mid statement is going to be extermely slow because it
will have to allocate a new string every time you assign to a character.
 
S

Scott M.

It really comes down to your opening statement: "I migrated VB6 code to
VB.Net". Just because you got the VB 6 code to "work" under .NET doesn't
mean it was written correctly (or "optimized") for .NET.

As someone who came to .NET from VB 6.0, it took me some time before the
"light bulb" went on in my head and I could finally understand the POWER
behind .NET. In .NET, everything is an object and so you've got to think
about how objects are allocated in memory and how objects interact.

As the other posts have said, StringBuilder is a solution to one of your
migration issues. In .NET, strings are not just a primitive data type, but
they are reference types and are "immutable". Once you set a value into a
string in .NET, memory is allocated on the managed heap for that string. If
its value should change, a new space on the heap must be allocated for the
new value and the old space abandoned. This would happen every time you
change the value of a string and is why using StringBuilder is the better
choice.


Richard506 said:
I migrated VB6 code to VB.Net and after building in the release mode and
setting Optimizations to Remove integer overflow checks and Enable
optimizations the exe runs at a miserably slow speed compared to VB6 exe.
Processing an 80k byte text file in VB6 takes less then a second.
The same code processs in VB.Net takes over a minute.
What am I overlooking?

The code is converting Un-typeable characters into typeable characters. It
is called "Stretch" and increases the length of the file a bit . It is from
an old Visual Basic book by John Craig.
 
C

Cor

Hi David,

Nice that test,
I was curious what would be if I changed that one piece of code where you
used a so called Microsoft Visual Basic function, to a string.char. Because
of that almost in the same time came that message from Tom, I did it also
with the Mid equivalent Substring.

nC = (Asc(Mid(msText, lI, 1)))

nC = (Asc(msText.Chars(lI)))

nC = (Asc(msText.Substring(lI, 1)))

The result was 100:60:100

In this case I expected that the chars would be faster, something we did in
a test with Jay B before. This time the mid function was not faster then the
substring, while in the test with Jay B the find was faster than the
indexof. For the char member is as far as I know no equivalent as a Visual
Basic function.

Cor
 
J

Jay B. Harlow [MVP - Outlook]

Richard,
In addition to all the other comments. The following articles provide a
wealth of information on writing .NET code that performs well.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/fastmanagedcode.asp

http://msdn.microsoft.com/library/d...y/en-us/dndotnet/html/highperfmanagedapps.asp

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/vbnstrcatn.asp

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechart/html/vbtchperfopt.asp

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/dotnetperftechs.asp

As the others have suggested, the rules have changed in VB.NET, what
performed well in VB6 may not perform well in VB.NET, the above articles
help identify some of the new rules, however not all of the new rules ;-)

Hope this helps
Jay


Richard506 said:
I migrated VB6 code to VB.Net and after building in the release mode and
setting Optimizations to Remove integer overflow checks and Enable
optimizations the exe runs at a miserably slow speed compared to VB6 exe.
Processing an 80k byte text file in VB6 takes less then a second.
The same code processs in VB.Net takes over a minute.
What am I overlooking?

The code is converting Un-typeable characters into typeable characters. It
is called "Stretch" and increases the length of the file a bit . It is from
an old Visual Basic book by John Craig.
 
J

Jay B. Harlow [MVP - Outlook]

Richard,
I should add, looking at your function, rather then a string builder I would
consider making sB a char array instead.

Remember that arrays are indexed starting with 0, so I will increment the
index after using it.
sB = Space(lA + (lA + 2) \ 3) 'New Stretched length
Dim sB(lA + (lA + 2) \ 3 -1) As Char
lJ = lJ + 1
Mid(sB, lJ, 1) = Chr((nC And 63) + 59)
sB(lJ) = Chr((nC And 63) + 59)
lJ = lJ + 1
lJ = lJ + 1
Mid(sB, lJ, 1) = Chr(nK + 59)
sB(lJ) = Chr(nK + 59)
lJ = lJ + 1

Then to return the value you can use the overloaded string constructor.

Return New String(sB)

One other item, remember that strings in VB.NET are Unicode, it would be
better (faster) to use ChrW & AscW instead of Chr & Asc.

Hope this helps
Jay

Richard506 said:
I migrated VB6 code to VB.Net and after building in the release mode and
setting Optimizations to Remove integer overflow checks and Enable
optimizations the exe runs at a miserably slow speed compared to VB6 exe.
Processing an 80k byte text file in VB6 takes less then a second.
The same code processs in VB.Net takes over a minute.
What am I overlooking?

The code is converting Un-typeable characters into typeable characters. It
is called "Stretch" and increases the length of the file a bit . It is from
an old Visual Basic book by John Craig.
 
W

will

Jay,

If you are using ASCII characters, a byte array will
be faster and save memory. I found using a byte array
instead of strings (string.len = 2.6 Meg) reduced my .Net
converted VB6 code run times several orders of magnitude.

Will
 
J

Jay B. Harlow [MVP - Outlook]

Will,
The problem with using a byte array over a char array, is it a hair more
work to get to and from a string. In this case to a string (as we only need
an "empty" array to begin with).

With a Char array you can use String.ToCharArray & String(Char) to go to &
from.

With a Byte array you have to get a System.Text.Encoding class involved,
assuming you are assured the string only has ASCII characters in it.

Never the less, I do agree with you I would expect a byte array to be
quicker, then a char array, but not by much as ChrW doesn't really do much.

Hope this helps
Jay
 
G

Guest

Thank you all for the answers.
So far, I have changed to the StringBuilder code and it has improved performance enormously.
BUT, it is still slower then the old code in VB6.
I'll keep trying
 
S

Scott M.

Something else to consider (and it may not play a factor with this code
you've supplied) but in VB.NET many of the old VB 6.0 functions are
superceded by object methods. While the old functions still work, the new
methods may perform better.

For example: msgbox() still works, but in .NET you have the MessageBox
class and it has a show method MessageBox.Show(). You'll find old string
functions have string object methods now, old date functions have date
object methods now, etc.
 
F

Fergus Cooney

Hi Richard,

Could you post the exact code that you are using in VB6 and in .NET? I'd
be interested in giving it a look. Tell me, too what sort of data we are
talking about. If it's all compressible to something reasonable small, you
could post a zip here. Another alternative is to email it to me:
(e-mail address removed). If you use email, you could send zips of complete projects,
which would make it easier for me to duplicate your results.(but please remove
anything that the compiler will recreate)

Regards,
Fergus
 
H

Herfried K. Wagner [MVP]

* "Fergus Cooney said:
If it's all compressible to something reasonable small, you
could post a zip here.

Please skip this sentence in future. Everybody posting here has an
email account nowadays. You may want to post a link to a website
offering free mail accounts instead. Thanks!
Another alternative is to email it to me:
(e-mail address removed). If you use email, you could send zips of complete projects,
which would make it easier for me to duplicate your results.(but please remove
anything that the compiler will recreate)

Really great idea!
 
T

Tom Shelton

Hi Richard,

Could you post the exact code that you are using in VB6 and in .NET? I'd
be interested in giving it a look. Tell me, too what sort of data we are
talking about. If it's all compressible to something reasonable small, you
could post a zip here. Another alternative is to email it to me:
(e-mail address removed). If you use email, you could send zips of complete projects,
which would make it easier for me to duplicate your results.(but please remove
anything that the compiler will recreate)

Regards,
Fergus

Actually, I'm with Fergus... I love these little performance challenges
:) If you could post the relevant code or send it to me via email, I
would love to play with it and see what could be done :)
 
F

Fergus Cooney

Herfried K. Wagner [PLS]

I want you to stop posting messages like the one to which I am responding.
They serve the purposes of nobody but Herfried K. Wagner [PLS]. They are
addressed to me and I do not welcome them.

You should have noticed [but I am aware that you are still highly emotional
and somewhat delusional] that these messages of yours, including the ones
containing snide remarks, are similarly not appreciated by others in this newsgroup.
Please take heed of this. As I've stated several times now, people stay very quiet
and think their thoughts. When people do start to make noises it is because they
<really are> concerned. Be careful Herfried K. Wagner [PLS] you are setting
yourself up dangerously here.

=================================

You are continuing to follow me around with these messages, I am now
of the judgement that you are stalking me. As mentioned before, stalking,
in Britain, and I assume Austria, is a serious offence.

This is your second warning.

=================================

In case you are not aware, your intolerance of people has been mentioned.
Now your pettiness is becoming noticable too. Many people would like you to
stop imposing rules upon them. Many people find your insistence upon rules to
be a waste of their time. It reflects <your> personality and needs as explained
elsewhere. It does not refect on the needs of the community as a whole (how
could it?) though there are, of course, others similar to you.

=================================
I have set up the following account to receive your messages:
(e-mail address removed)

If this is not to your liking and you wish to have a public battle, I
invite you to microsoft.public.nntp.test. In that arena we can move Heaven
and Earth and nobody will be watching and nobody will care. This lack of
publicity may not suit you but I will no longer battle with you in this group.

Fergus

ps. An apology from you to the community will be appropriate when you
come to your senses and can do it with sincerity. That is, if you do
belong to this community and care for the people herein.
 
H

Herfried K. Wagner [MVP]

* "Fergus Cooney said:
Herfried K. Wagner [PLS]

Please stop insulting me!
of the judgement that you are stalking me. As mentioned before, stalking,
in Britain, and I assume Austria, is a serious offence.

Insulting people in the publicity is a _serious offence_.
I have set up the following account to receive your messages:
(e-mail address removed)

Very friendly. Other people in the groups will now be able to get the
right picture of Fergus Cooney. Go away.
 
F

Fergus Cooney

Herfried,

Use OT (as per your own instructions)

Restrict your posts to technical issues (as per your own instructions)

Email me (as per your own instructions)

Or take it to the nntp.test group.

Fergus
 
H

Herfried K. Wagner [MVP]

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top