Is .NET slower than - say - VB6?

N

news.microsoft.com

Hi all,

First post here. I'm porting an application I wrote in VB6, over to VB.NET
2005.

It could be said I'm really struggling with some (most!) of the syntax of
VB.NET 2005, but I'm getting there. I'm relying a lot, at this point, on
sample code from Microsoft, and other forums about the Internet.

One thing I've painfully noticed (hence the title of this post) is .NET
seems to be GOD AWEFULLY slow!

My VB6 version of my app interacts HEAVILY with Active Directory. My VB6
program starts in approximately 10 seconds, loading all 1300-odd Active
Directory user accounts in a listview.

VB.NET (doing the same thing and based on an example from MSDN) takes almost
60 seconds!

WMI is also painfully slow. A "DiskQuota" DLL call to the server to get
volume useage info under VB6 is instant. A WMI call to get the same
information takes 30 or more seconds.

Why is this? My workstation/VB.NET 2005 platform is Windows XP 64-bit, fully
updated, running on a P4-3.2GHz, 1Gb RAM. My server is Server 2003 SP2 (two
dual core 3.2GHz Xeons). My network is fine.

I'm attempting to port my program to VB.NET to get cross-platform
compatibility. 32-bit/64-bit/workstation and server. My program needs to run
on them all. A 32-bit program using 32-bit DLLs simply won't work on a
64-bit platform - hence the port.

Is .NET inherently slower than VB6 where VB6 is using whatever 32-bit DLL is
needed to get the job done?

Mark
 
C

Cor Ligthert [MVP]

Is .NET inherently slower than VB6 where VB6 is using whatever 32-bit DLL
is
needed to get the job done?
When well done it can be about 10 times quicker

When bad done it can be about 10 times slower.

Basicly it is quicker as it does not use late binding.

Cor
 
K

kimiraikkonen

Hi all,

First post here. I'm porting an application I wrote in VB6, over to VB.NET
2005.

It could be said I'm really struggling with some (most!) of the syntax of
VB.NET 2005, but I'm getting there. I'm relying a lot, at this point, on
sample code from Microsoft, and other forums about the Internet.

One thing I've painfully noticed (hence the title of this post) is .NET
seems to be GOD AWEFULLY slow!

My VB6 version of my app interacts HEAVILY with Active Directory. My VB6
program starts in approximately 10 seconds, loading all 1300-odd Active
Directory user accounts in a listview.

VB.NET (doing the same thing and based on an example from MSDN) takes almost
60 seconds!

WMI is also painfully slow. A "DiskQuota" DLL call to the server to get
volume useage info under VB6 is instant. A WMI call to get the same
information takes 30 or more seconds.

Why is this? My workstation/VB.NET 2005 platform is Windows XP 64-bit, fully
updated, running on a P4-3.2GHz, 1Gb RAM. My server is Server 2003 SP2 (two
dual core 3.2GHz Xeons). My network is fine.

I'm attempting to port my program to VB.NET to get cross-platform
compatibility. 32-bit/64-bit/workstation and server. My program needs to run
on them all. A 32-bit program using 32-bit DLLs simply won't work on a
64-bit platform - hence the port.

Is .NET inherently slower than VB6 where VB6 is using whatever 32-bit DLL is
needed to get the job done?

Mark

Hi,
A little addition,GDI+ is also so slow on older machines because of
not having hardware acceleration. Hope to see same performance like
in DirectX in future.

Regards,

Onur
 
G

Galen Somerville

news.microsoft.com said:
Hi all,

First post here. I'm porting an application I wrote in VB6, over to VB.NET
2005.

It could be said I'm really struggling with some (most!) of the syntax of
VB.NET 2005, but I'm getting there. I'm relying a lot, at this point, on
sample code from Microsoft, and other forums about the Internet.

One thing I've painfully noticed (hence the title of this post) is .NET
seems to be GOD AWEFULLY slow!

My VB6 version of my app interacts HEAVILY with Active Directory. My VB6
program starts in approximately 10 seconds, loading all 1300-odd Active
Directory user accounts in a listview.

VB.NET (doing the same thing and based on an example from MSDN) takes
almost 60 seconds!

WMI is also painfully slow. A "DiskQuota" DLL call to the server to get
volume useage info under VB6 is instant. A WMI call to get the same
information takes 30 or more seconds.

Why is this? My workstation/VB.NET 2005 platform is Windows XP 64-bit,
fully updated, running on a P4-3.2GHz, 1Gb RAM. My server is Server 2003
SP2 (two dual core 3.2GHz Xeons). My network is fine.

I'm attempting to port my program to VB.NET to get cross-platform
compatibility. 32-bit/64-bit/workstation and server. My program needs to
run on them all. A 32-bit program using 32-bit DLLs simply won't work on a
64-bit platform - hence the port.

Is .NET inherently slower than VB6 where VB6 is using whatever 32-bit DLL
is needed to get the job done?

Mark
I have a VB6 app that gets Heart beats in real time over a USB connection.
The app displays the Heart sound and the ECG at rates up to 400
Beats-per-minute.

So far I have been able to get VB2005/VB2008 up to about 3 Beats-per-minute.

Galen
 
S

Smokey Grindel

if you see a difference like that then you are doing something wrong...
because I can control a 2 mpixel LED display via USB through a .NET app...
if I can push that kinda data you should be able to do something that does
very little data wise like pull ECG dta...
 
G

Galen Somerville

The USB is supplying 24 bytes, say, every 4 ms (2 sets of 6 integers at 75
BPM). The display has to blank the previous 12 lines before it can write the
12 new lines. Each line is from pixel X to pixel X+1. The Y portion could be
a hundred pixels high.

Galen
 
M

Michel Posseth [MCP]

You can still take the API way in VB.Net
When well done it can be about 10 times quicker

When bad done it can be about 10 times slower.

If you have 2 fully optimized assembly`s in both languages you might see
some surprising results depending on the situation
i have seen a program written in good old C doing file io that blew anny
other program away , however it was only for this specific task so fast as
it was optimized for this one situation .

In some way COBOL is also superior to .Net or VB6 ,,,,, but it is the whole
package that counts for me :)
Basicly it is quicker as it does not use late binding.

VB6 is fully written on COM and it can use both Early and late binding ( by
the way i can also late bind with VB.Net for instance to office if i am not
sure if it is installed on the target system )


For VB6 COM is native so i guess that if you use libs through COM VB6 will
be a few miliseconds quicker, However VB.Net is not obsolete as VB6 is and
for native .Net assemblys the speed is mostly equal or faster .


just my thoughts

Michel
 
C

Cor Ligthert[MVP]

Michael,

What is in your opinion Native code as that is in my idea always often used,
however never is specified what is meant by that.

You mean Intel Assembler?

In my idea are there very few languages that creates code on this level,
while it than would be extremely huge and therefore slow to handle.

As you know my thoughts.

Cor
 
M

Michel Posseth [MCP]

Hello Cor ,

In the context of VB6 and COM , i mean with "Native" that VB6 is specially
designed for COM as minimal marshalling is necesary you have less overhead
and thus more speed as non native interaction .

With .Net and the context "Native" i mean .Net libraries that are written
in .Net


Usercode written in VB6 <---interaction ----> Library used is COM =
Native
Usercode written in .Net <---interaction ----> Library used is .Net =
Native

Usercode written in .Net <---interaction ----> Library used is COM =
Non Native ( interop necesary )

For a lot of the old COM libs there are nowadays a lot .Net libs or
alternatives availlable that is what i tried to say

regards

Michel
 
M

Michel Posseth [MCP]

An example of my own experience

I had to write once a data conversion app from plain text files of a few GB
as this was a internall project of our own company i decided to try some
new technology`s and so i used a then a early beta version of .Net .

I had some big laughs with my collegues , cause it was so slow our VB6 app
did it in a fraction of the time !!! hahaha :)
a year later we then worked for several projects with .Net and i had a lot
more experience with .Net and had read some good books , we then had to do a
new conversion on a new version of that same data , i opened my previous
..Net project and laughed about my own stupidity for instance one of the big
botle necks in my prog was that i used a concat of string variabels where i
should have used a string builder object , why didn`t i thought of that
before well as i was looking at the .Net prog with VB6 experience and common
knowledge ( VB6 doesn`t have a string builder , and i wasn`t aware of its
existence in .Net ) .

I altered the prog with the knowledge i posessed at that time about the
framework and the VB.Net prog blew the VB6 prog to the moon in terms of
speed
..Net was superior in speed now .

VB6 ISNOT VB.Net you should really buy yourself a good reference i would
recomend the Balena book "Programming Microsoft Visual Basic" and allow
yourself some studying and play time .

HTH

Michel
 
A

AMercer

IMHO your best is to first narrow down the portion that is so slow (for
example it would be interesting to see if this is the listview (UI) part or
the ADSI interaction) and then post about this particular code.

Patrice may have the answer to the first problem. Your performance problem
could be entirely with loading the listview. Comment out listview updates
and see how long it takes. Generally, you want to batch updates like this
because feeding one line at a time is slow. You can batch updates with
AddRange().
 
S

ShaneO

Michel said:
I altered the prog with the knowledge i posessed at that time about the
framework and the VB.Net prog blew the VB6 prog to the moon in terms of
speed
.Net was superior in speed now .

VB6 ISNOT VB.Net you should really buy yourself a good reference i would
recomend the Balena book "Programming Microsoft Visual Basic" and allow
yourself some studying and play time .
Michel is 100% correct here.

I only switched-over to VB2005 from VB6 a couple of years ago and I
distinctly recall all the speed issues I was having at that time. There
were many times that I thought I'd simply give-up, but then I'd push
myself to continue to struggle with .NET.

Now I wouldn't have it any other way! Sure, there are still a couple of
minor issues with the speed of the UI, but now that I've educated myself
in using the correct commands and tools exposed by .NET, I am entirely
satisfied with the speed. I would even go as far as to say that I can
now obtain higher overall performance from my .NET apps than I could
ever have expected from VB6.

Just stick with it, read as much as you can, and ask as many questions
on specific issues as you need. Concentrate on fixing individual
routines that are creating bottlenecks, one at a time, and you'll
progressively learn the new/better/right way to do it.

You will eventually be glad of the change.


ShaneO

There are 10 kinds of people - Those who understand Binary and those who
don't.
 
N

news.microsoft.com

Thankyou everyone, for your comments - they have been most illuminating.I'll
post some code now - please don't bag my coding, or use terms like "You
idiot..". A lot of the code I've used has been modified to suit the
environment.

Here is the VB6 code which can pull in all 1300-odd Active Directory
accounts in less than 10 seconds. Notice it is essentially an SQL command,
and I'm telling the server to return the sAMAccount Name, SN, & GivenName,
and sort by sAMAccountName, in ascending order. THIS CODE IS RIPPINGLY FAST.

Const ADS_SCOPE_BASE = 0
Const ADS_SCOPE_ONELEVEL = 1
Const ADS_SCOPE_SUBTREE = 2

' Bind to the Active Directory with the RootDSE object.
Set rootDSE = GetObject("LDAP://RootDSE")
sObjectDN = "LDAP://" & rootDSE.Get("defaultNamingContext")
Set rootDSE = Nothing
Set oIADs = GetObject(sObjectDN)

' Open a Connection object.
con.Provider = "ADsDSOObject"

' Open the connection.
con.Open "Active Directory Provider"

' Create a command object on this connection.
Set Com.ActiveConnection = con

' Set the query string using SQL Dialect.
Com.CommandText = "Select SAMAccountName, SN, GivenName from '" &
oIADs.ADsPath & "' where objectCategory='user' ORDER BY SAMACCOUNTNAME ASC"

' Set the preferences for Search
Com.Properties("Page Size") = 1000
Com.Properties("Timeout") = 30 'seconds
Com.Properties("searchscope") = ADS_SCOPE_SUBTREE
Com.Properties("Chase referrals") = &H40 'ADS_CHASE_REFERRALS_EXTERNAL

' Do not cache the result, it results in less memory requirements.
Com.Properties("Cache Results") = False
'Com.Properties("Size limit") = 999
' Execute the query.
Set Rs = Com.Execute

If Not Rs.EOF Then
Rs.MoveFirst
End If

' Navigate the record set.

Do While Not Rs.EOF

Set newline = lstUsers.ListItems.Add(, , UCase(Rs.Fields(2)))
newline.SubItems(1) = Rs.Fields(0) & " " & Rs.Fields(1)

Set newline = Nothing

Rs.MoveNext

Loop

-----------------------------------------------------------------------------------------------------

This is the VB.NET code. This was got from Microsoft's example "Basic
Directory search". Modified to load a ListView, rather than output to
console. Interestingly, as I debugged the code just now, the slowdown
appears to be in the listview loading (as you've all observed, my VB.NET
coding skills just hain't what they orter be!) Suggestions are most
welcome.... - This code takes upwards of 45 seconds to execute...

Dim searcher As New DirectorySearcher()

' Will perform a search of <schemaClassNameToSearch> objects in
' current(domain)
searcher.SearchRoot = New DirectoryEntry(domainADsPath, username,
password) ' password is null, username is null, since I am admin.
DomainADsPath = LDAP://MYDOMAIN.COM.AU
searcher.Filter = "(objectClass=user)"
searcher.SearchScope = SearchScope.Subtree
'searcher.Sort = New SortOption("sAMAccountName", ) ',
SortDirection.Ascending) 'Sort direction Ascending is removed, since
the ListView is set to sort A - Z.
' If there is a large set to be return set page size for a paged
search
searcher.PageSize = 512
searcher.PropertiesToLoad.Add("sAMAccountName").ToString()
searcher.PropertiesToLoad.Add("GivenName").ToString()
searcher.PropertiesToLoad.Add("SN").ToString()

Dim results As SearchResultCollection = searcher.FindAll()

Dim result As SearchResult
For Each result In results ' This is the bit it seems to choke
on. Is this where the search is executed, somehow?
Dim lvi As New ListViewItem
If
Strings.Right(result.GetDirectoryEntry().Properties("sAMAccountName").Value,
1) <> "$" Then 'no machine names
lvi.Text =
Strings.UCase(result.GetDirectoryEntry().Properties("sAMAccountName").Value)
lvi.SubItems.Add(result.GetDirectoryEntry().Properties("GivenName").Value
& " " & result.GetDirectoryEntry().Properties("SN").Value)
Form1.lstUsers.Items.Add(lvi)
End If
Next result
results.Dispose()



Thanks all!

Mark
 
M

Michel Posseth [MCP]

Hello Mark ,

can you invesitigate what this small mod does to the perfomance ?
as the listview is known for it`s slowdown behavior i added 2 method calls
at the start and end of the loop



Dim searcher As New DirectorySearcher()


' Will perform a search of <schemaClassNameToSearch> objects in
' current(domain)
searcher.SearchRoot = New DirectoryEntry(domainADsPath, username,
password) ' password is null, username is null, since I am admin.
DomainADsPath = LDAP://MYDOMAIN.COM.AU
searcher.Filter = "(objectClass=user)"
searcher.SearchScope = SearchScope.Subtree
'searcher.Sort = New SortOption("sAMAccountName", ) ',
SortDirection.Ascending) 'Sort direction Ascending is removed, since
the ListView is set to sort A - Z.
' If there is a large set to be return set page size for a paged
search
searcher.PageSize = 512
searcher.PropertiesToLoad.Add("sAMAccountName").ToString()
searcher.PropertiesToLoad.Add("GivenName").ToString()
searcher.PropertiesToLoad.Add("SN").ToString()


Dim results As SearchResultCollection = searcher.FindAll()


Dim result As SearchResult
Form1.lstUsers.BeginUpdate()
For Each result In results ' This is the bit it seems to choke
on. Is this where the search is executed, somehow?
Dim lvi As New ListViewItem
If
Strings.Right(result.GetDirectoryEntry().Properties("sAMAccountName").Value­,
1) <> "$" Then 'no machine names
lvi.Text =
Strings.UCase(result.GetDirectoryEntry().Properties("sAMAccountName").Value­)

lvi.SubItems.Add(result.GetDirectoryEntry().Properties("GivenName").Value & "
" & result.GetDirectoryEntry().Properties("SN").Value)
Form1.lstUsers.Items.Add(lvi)
End If
Next result
Form1.lstUsers.EndUpdate()


Regards

Michel


results.Dispose()
 
B

Bill McCarthy

I'd turn off sorting on the treeview and let the search sort instead. Try
this code:

With searcher
.SearchRoot = New DirectoryEntry(domainAdsPath, username, password)
.SearchScope = SearchScope.Subtree
.Filter = "(objectClass=user)"
.Sort = New SortOption("sAMAccountName", SortDirection.Ascending)
.PageSize = 1000
.PropertiesToLoad.Add("sAMAccountName")
.PropertiesToLoad.Add("GivenName")
.PropertiesToLoad.Add("SN")
End With

Using results As SearchResultCollection = searcher.FindAll()

Dim items As New List(Of ListViewItem)

For Each result As SearchResult In results
Dim props As PropertyCollection =
result.GetDirectoryEntry.Properties
Dim lvi As ListViewItem

Dim accountname As String =
props.Item("sAMAccountName").Value.ToString
If accountname.EndsWith("$") Then Continue For

lvi = New ListViewItem(accountname.ToUpper)
lvi.SubItems.Add(props.Item("GivenName").Value.ToString & " " &
props.Item("SN").Value.ToString)
items.Add(lvi)
Next result

lstUsers.Items.AddRange(items.ToArray)

End Using
 
N

news.microsoft.com

Mmmm... both excellent! Give me a while - I'm off to bed now - I'll check it
out tomorrow!

Mark
 
D

Dick Grier

There are things that ARE slower when executing in .NET vs VB6. BTW, a
ListBox is very slow to update -- even in VB6, and it is worse in .NET.

--
Richard Grier, MVP
Hard & Software
Author of Visual Basic Programmer's Guide to Serial Communications, Fourth
Edition,
ISBN 1-890422-28-2 (391 pages, includes CD-ROM). July 2004, Revised March
2006.
See www.hardandsoftware.net for details and contact information.
 
N

news.microsoft.com

Hi all,

In my testing today, I've found the problem is "For Each result in results".

In my production environment, it has to loop 1384 times (for each Active
Directory account).

I discovered I can remove the "If Strings.Right..<> $" If Then statement by
refining what is returned from Active Directory. I also re-instated the
Sort.Direction Ascending (and removed "sorted" from the ListView
properties).

I also tried the "BeginUpdate()" method.

None of the above worked.

The .NET code takes between 18 and 23 seconds to loop 1384 times (on a
64-Bit Server 2003 box running VB.NET 2005). VB6 does it (and other things)
in less that three seconds.

I discovered I need to use the "AddRange" method in the ListView, but I have
no idea how AddRange works. I surfed the 'net extensively, and people have
reported using AddRange works a treat, but none posted their code.

One thing I am curious about with AddRange. If I can build an array of
ListView items to be added, why can't I just take my Active Directory search
results array "Dim results As SearchResultCollection = searcher.FindAll()"
bit, and slam that array in to the ListView with an AddRange?

Any clues to using AddRange would be most welcome, since Microsoft's help on
this subject is somewhat unwelcoming.

Mark
 
B

Bill McCarthy

Hi Mark,

I believe the sample code I posted the other day uses AddRange. Did you
test that ?
 

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