Re: tips for optimizing vb code
Quote:
Originally Posted by Maven
I normally go to asm when I have a very long switch because there is some cool tricks in asm you can do that you simply cannot do in any other langauge. I can compare a charecter with every charecter in the ascii set with 1 compare statement in asm where it would take around 255 in any other langauge.
A jump table is automatically generated by some C++ compilers when the switch statement is used with many cases (at least 4 for Borland C++).
I verified it for Borland C++ and gcc.
The standard says that the switch statement can only handle constants cases. And i am sure that the standard was thinking about jump tables.
Moreover for some special cases it is easy to manually manipulate table of pointers to function in C++ (but of course, it does not replace JUMP tables).
But, VB don't uses these optimizations.
Re: tips for optimizing vb code
Quote:
Originally Posted by SuperKoko
On Pentium, but it is faster with newer processors.
For example, i remember that a division uses 18 clock cycles on AMD K6-2 processors.
In fact, a multiplication by 0.5 is slower, because it converts the long to a float (moving the data on the stack), then it does the multiplication, and convery the result to long.
And conversions from integer to float and float to integer are relatively slow.
I compared the two operations in C++, with MinGW and Borland C++ 5.5.
And the integer division is about 1.8 times faster with my K6-2 333Mhz processor for MinGW (In fact, with a constant division factor the integer division is optimized like a multiplication by the number inverse, and in that case an integer division by 3 is 5 times faster than the float division).
An integer division by 2 is even faster, because it uses an arithmetic shift.
Borland's compiler uses extremely slow code to convert floats to integers (i don't understand why, but that is the case), so it is 5 times slower with float than with integers.
Conclusion : use float multiplications when variables are floats, and integer division when variables are integers.
Divison is the most expensive instruction to preform on any cpu, in other words its the most expensive instruction in the x86 language. I don't care what CPU you have, it's always going to be the slow instruciton because of the things the CPU has to do to get a result.
Don't put too much stock in open source compilers like MinGw. Compiler design is one of the hardest things to create. If you have a compiler that generates poorly optimized code or even no optimization, it's pointless to attempt to speed up anything. Take microsoft's standard edition of c++ .net. About every trick I'm showing is completely pointless to anyone who has that version of C++, because optmizations are not enabled in that compiler.
I think you're getting confused on what a jump table is. Select case statements do make a Table like looking code, however it's not the same thing I am talking about. Basically a variable is created to store offsets of every single label. So if you have 10 different things you want to test for, you would have a variable that is 10x4 bytes long. In each 4 bytes a memory location would be stored there, for each of the 10 items.
In asm it would looking something like this:
MyTable dd Label1, Label2, Label3, Label4, Label5, Label6, .... Label10
Then on down to where you would normally be making compares, you would simple say:
jmp [MyTabel+mytestvar]
Label1
....
...
..
Label2
...
...
..
And that one statement will automatically go to the code needed to be performed for that given input.
It's an optimization that compilers cannot really do because there is very special things that have to be met in order for it to work. In other words, you're tested input must be in some form of series and not random crap. If it was just a few numbers from 1 to 1,000,000, it would require 4x1,000,000 bytes to create the table just to perferm tests on a handful of numbers. It would be better in that case to use a different method.
Re: tips for optimizing vb code
Ok, seeing as this is a topic for code optamization.
Does anyone have any information in using GoTo's?
I use a few in my code and were wondering how they would affect the code :)
Cheers,
RyaNJ
Re: tips for optimizing vb code
Quote:
Originally Posted by sciguyryan
Ok, seeing as this is a topic for code optamization.
Does anyone have any information in using GoTo's?
I use a few in my code and were wondering how they would affect the code :)
Cheers,
RyaNJ
You should never use Gotos in code. It breaks the entire concept of structured programming.
Re: tips for optimizing vb code
Quote:
Originally Posted by Maven
You should never use Gotos in code. It breaks the entire concept of structured programming.
Maven - that wasn't the question!
With all the constructs available in VB - IF/THEN/ELSE, SELECT/CASE - boolean variables - looping - there are many better ways to flow through logic in VB than to use GOTO.
As far as speed - I can see no reason why GOTO would be faster than a properly coded IF/THEN/ELSE.
Re: tips for optimizing vb code
Quote:
Originally Posted by szlamany
With all the constructs available in VB - IF/THEN/ELSE, SELECT/CASE - boolean variables - looping - there are many better ways to flow through logic in VB than to use GOTO.
Still I've found (actually, very few) situations where a goto was the only way out I could think of. I just can't remember where I stored the specific example I have in mind, but I think it was something having to do with exiting from the innermost nested loop to one of the outer shelling loops.
Re: tips for optimizing vb code
Quote:
Originally Posted by krtxmrtz
Still I've found (actually, very few) situations where a goto was the only way out I could think of. I just can't remember where I stored the specific example I have in mind, but I think it was something having to do with exiting from the innermost nested loop to one of the outer shelling loops.
Thats exactly my point, it would be much too complex to do with out them (ANd I only use 4 of them dso don't fret ;))
I only wanted to know if they would effect the speed of the opperation abd by how much :)
I don't think it will have much effect seeing as I only use 4 anyway :)
Cheers,
RyanJ
Re: tips for optimizing vb code
Goinh back to the subject of slow division, might need some help here Maven:
Dividing without dividing
Re: tips for optimizing vb code
Is
with form
.text1.text = a
end with
Then same as
form1.text1.text = a
?
Re: tips for optimizing vb code
Quote:
Originally Posted by Krenshau
Is
with form
.text1.text = a
end with
Then same as
form1.text1.text = a
?
See this thread
http://www.vbforums.com/showthread.p...highlight=dots
Especially around post #30...
Re: tips for optimizing vb code
Quote:
Originally Posted by krtxmrtz
Still I've found (actually, very few) situations where a goto was the only way out I could think of. I just can't remember where I stored the specific example I have in mind, but I think it was something having to do with exiting from the innermost nested loop to one of the outer shelling loops.
I prefer to use Exit's over Goto statements where possible i.e.
Instead of using this
Code:
Public Sub Math(ByRef a as integer)
Select Case a
Case 1
a = a + 1
Case 2
b = b + 1
Goto DoMath
Case Else
' for other numbers
End Select
Exit Sub
DoMath:
' The only code that will work past here would be Case 2
a = a * b
I would rather use this
Code:
Public Sub Math(ByRef a as integer)
Select Case a
Case 1
a = a + 1
Exit Sub
Case 2
b = b + 1
Case Else
' for other numbers
Exit Sub
End Select
' The only code that will work past here would be Case 2
a = a * b
End Function
Thats just me though, sorry for messy code I wrote this in notepad heh
Re: tips for optimizing vb code
Quote:
I only wanted to know if they would effect the speed of the opperation abd by how much
I think he was referring to goto performance wise - goto will perform the same speed as if...then....else or perhaps faster in some cases - its actually just translated to the asm 'jmp' so it doesn't really have performance implications. The main thing most ppl complain about is that its jsut a bad programming practice.
I tend to disagree with the propaganda from these 'programming practices' but I tend to adhere to them for convenience sake and readability sake. Use Gotos when necessary and don't use them when unnecessary.
The main case where the goto wins on efficiency is when there is a internal nested loop or something and you need to get out of it - maybe going through two other loops. One way is to use if then and use flags to say the loop is terminated and i want to get out or just use a simple GOTO statment and get out. The latter would be the best approach - because it is faster and is only 1 line of code (and a 2nd line for the label). Other than that you probably manage all with if....then....else.
The above code with exit subs performance wise should actually be faster because it leaves the sub directly at each branch rather needing to jump.
Re: tips for optimizing vb code
Quote:
Originally Posted by dee-u
Unless disproved by others I believe these would also optimize vb code
using textbox = 'your text' over textbox.text = 'your text'
using label = 'your caption' over label.caption = 'your caption'
etc....
etc....
I disagree on leaving the compiler to fill in the default to speed up your code
because that is what happens the compiler generate's the same code anyways and it isn't faster unless you add typing code to the equasion :bigyello:
A serious speed tip for arrays
if you want to delete or insert an item in an array with fixed lenght items like longs,
bytes, fixed length array or UDT made out of these types use memcopy to shift the values:
example for a array of longs
VB Code:
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(dest As Any, source As Any, ByVal numBytes As Long)
Sub InsertItemToLongArray(LongArr() As Long, Index As Long, NewItem As Long)
' using LenB() to evaluate size so it can be used easily for other type
' arrays just by altering the argument types (in speed critical circumstances
' you can hardcode these lengths ofcourse)
If Index < UBound(LongArr) Then
CopyMemory LongArr(Index + 1), LongArr(Index), (UBound(LongArr) Index) * LenB(LongArr(Index))
End If
LongArr(index) = NewItem
End Sub
Sub DeleteItemFromLongArray(LongArr() As Long, Index As Long)
If index < UBound(LongArr) Then
CopyMemory LongArr(Index), LongArr(Index + 1), (UBound(LongArr) - Index) * LenB(LongArr(Index))
End If
LongArr(Index) = vbEmpty
End Sub
NOTE: do not use this for arrays containing Objects, Dynamic Strings UDT's containing these kind of objects. It will bring the app down for sure.
Re: tips for optimizing vb code
I'd just like to point out that there is a HUGE difference between a for loop and a Do loop in visual basic. I found this out in my younger days while trying to debug something. My code was something similar to (but obviously not as stupid as):
VB Code:
public function something(byval s as string) as boolean
dim A as long
for a = 1 to len(s)
s = left(s, len(s) - 1)
next a
end function
Now, granted the code calculates len(s) constantly in the loop, but my problem was it kept giving me out of bounds errors. It turns out that a for loop STORES THE VALUE OF LEN(S) at the start and then loops through! You get the same thing when you use the "With" command.
Try this code out as well:
VB Code:
'In Class1
Option Explicit
Public Name As String
'In a form
Option Explicit
Private Sub Form_Load()
Dim A As Class1
Dim B As Class1
Dim C As Class1
Set A = New Class1
Set B = New Class1
A.Name = "A"
B.Name = "B"
Set C = A
With C
Set C = B
MsgBox .Name
End With
End Sub
"A" pops up.
Re: tips for optimizing vb code
The for loop thing is just a normal behavior for a loop: there is just no point recalculating the value. This also makes for loop faster (= a more efficient choice) than do loop in some situatations.
I don't see anything wrong with the With statement either, because that's just how it works: With will Reference to class A since C is just a reference to class A; or more so exactly the same as class A. This clarifies why With statement works as it does:
VB Code:
Option Explicit
Private Sub Form_Load()
Dim A As Class1
Dim B As Class1
Dim C As Class1
Set A = New Class1
Set B = New Class1
A.Name = "A"
B.Name = "B"
Set C = A
With C
Set C = B
.Name = "1"
C.Name = "2"
MsgBox "A: " & A.Name & " - B: " & B.Name
End With
End Sub
Re: tips for optimizing vb code
Quote:
Originally Posted by Merri
The for loop thing is just a normal behavior for a loop: there is just no point recalculating the value. This also makes for loop faster (= a more efficient choice) than do loop in some situatations.
I don't see anything wrong with the With statement either, because that's just how it works: With will Reference to class A since C is just a reference to class A; or more so exactly the same as class A. This clarifies why With statement works as it does:
VB Code:
Option Explicit
Private Sub Form_Load()
Dim A As Class1
Dim B As Class1
Dim C As Class1
Set A = New Class1
Set B = New Class1
A.Name = "A"
B.Name = "B"
Set C = A
With C
Set C = B
.Name = "1"
C.Name = "2"
MsgBox "A: " & A.Name & " - B: " & B.Name
End With
End Sub
Yes yes, I know that's how it works and appreciate. I was just pointing it out for everyone. I found the With behavior very "huh?!" at first. I thought the compiler was just adding the "c" back in front.
Re: tips for optimizing vb code
Maybe it would be better to point it out in the FAQ forum instead of a thread dedicated for optimization? Atleast that'd make it clear for us to understand you're pointing out something and not wondering it :)