# Thread: using arrays and can i speed up my for loop?

1. ## using arrays and can i speed up my for loop?

heres my actual for loop on 2D array:
Code:
```Private Sub DrawMap()
Dim x As Integer
Dim y As Integer
Dim PosX As Integer
Dim PosY As Integer
Dim clr As ColorConstants

PosX = 0
PosY = 0
For y = 0 To 9
For x = 0 To 9
clr = LevelMap0(y)(x)
If (clr = 1) Then clr = vbBlue
If (clr = 0) Then clr = vbWhite
Picture1.FillColor = clr
Rectangle Picture1.hdc, PosX, PosY, PosX + 33, PosY + 33
PosX = PosX + 33
Next x
If ((PosY / 33) < 9) Then PosX = 0
PosY = PosY + 33
Next y

'Picture1.Circle (Player.PosX, Player.PosY), 5, vbGreen
Picture1.FillColor = vbYellow
Ellipse Picture1.hdc, Player.PosX - 4, Player.PosY - 4, Player.PosX + 4, Player.PosY + 4
DrawLine Picture1.hdc, Player.PosX, Player.PosY, Player.PosX + Cos(Player.Radians) * 30, Player.PosY + Sin(Player.Radians) * 30
Picture1.Width = PosX
Picture1.Height = PosY
End Sub```
if i comment:
Code:
`clr = LevelMap0(y)(x)`
i can win 100FPS or more....
so is there another way for speed up the FOR loop?

2. ## Re: using arrays, can i speed up my for loop?

You should probably write that as:

Code:
`clr = LevelMap0(x, y)`
Also you can gain some performance in your executable if you turn on the advanced compiler optimization "Remove Array Bounds Checks".

3. ## Re: using arrays, can i speed up my for loop?

Yeah, I don't think we know what LevelMap0 is doing, but it looks like you might try to optimize that function to find more speed.

And yeah, as VanGogh stated, turning off "Array Bounds Checks", as we as checking all the other "Advanced Optimizations", can give you surprising performance boosts (multiples of what you're now getting).

I've actually compiled code in a separate ActiveX DLL in the past with these performance boosts for things similar to what you're doing. I put them in a DLL, so I didn't have to lose all those "checks" in my entire main project. Compiling in a separate ActiveX DLL allows you to specify which "Advanced Optimizations" you want in each compiled piece of code.

4. ## Re: using arrays, can i speed up my for loop?

You know? I keep thinking about that LevelMap0 function. If it's taking a single argument, and then returning an array, which you're subsequently addressing, that's a BIG reason for the slowdown. If that's the case, each time you call that function, it's allocating memory for that entire array, and shuffling memory all over the place.

That needs to be fixed. You need to just pass in two arguments, and return a single value.

5. ## Re: using arrays, can i speed up my for loop?

Lol! Elroy, You are wasting your time thinking about the "function". I am pretty sure LevelMap0 is a variant array of arrays, which btw, should be avoided in a time critical function.

6. ## Re: using arrays, can i speed up my for loop?

When you have your LevelMap0 in a 2D array i.e. addressing it like LevelMap0(x, y) then you can prevent array bounds checks from killing your performance in IDE (and compiled w/ no adv. optimizations set) by using For Each vColor In LevelMap0 â€” a little known fact that arrays of higher dims (more than 1D) can be iterated too which does not involve bound checks under any optimization settings incl. in IDE.

7. ## Re: using arrays, can i speed up my for loop?

not sure how many times I need to repeat myself
work in memory first.
render only the finished product.

that will speed it up.

also, this

Code:
```clr = LevelMap0(y)(x)
If (clr = 1) Then clr = vbBlue
If (clr = 0) Then clr = vbWhite```
can be optimized so the LevelMap0 will return the color directly
so clr will be vbBlue/vbWhite or whatever other color.

another thing to consider is "static" objects. those can be created one time and used many times with just a simple bitblt/alphablend.

8. ## Re: using arrays, can i speed up my for loop?

thank you so much for your tip.. and i win much more performance:
instead numbers, i use the the constants colors names
Code:
```Dim LevelMap0(10) As Variant
LevelMap0(0) = Array(vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue)
LevelMap0(1) = Array(vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue)
LevelMap0(2) = Array(vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue)
LevelMap0(3) = Array(vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue)
LevelMap0(4) = Array(vbBlue, vbWhite, vbWhite, vbBlue, vbBlue, vbBlue, vbWhite, vbWhite, vbWhite, vbBlue)
LevelMap0(5) = Array(vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue, vbWhite, vbBlue)
LevelMap0(6) = Array(vbBlue, vbWhite, vbWhite, vbBlue, vbBlue, vbBlue, vbWhite, vbWhite, vbWhite, vbBlue)
LevelMap0(7) = Array(vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue)
LevelMap0(8) = Array(vbBlue, vbWhite, vbWhite, vbWhite, vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue)
LevelMap0(9) = Array(vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue)
'now i can test it:
Private Sub DrawMap()
Dim x As Integer
Dim y As Integer
Dim PosX As Integer
Dim PosY As Integer
Dim col As ColorConstants

PosX = 0
PosY = 0
For y = 0 To 9
For x = 0 To 9
col = LevelMap0(y)(x)
Picture1.FillColor = col
Rectangle Picture1.hdc, PosX, PosY, PosX + 33, PosY + 33
PosX = PosX + 33
Next
If ((PosY / 33) < 9) Then PosX = 0
PosY = PosY + 33
Next

Picture1.FillColor = vbYellow
Ellipse Picture1.hdc, Player.PosX - 4, Player.PosY - 4, Player.PosX + 4, Player.PosY + 4
DrawLine Picture1.hdc, Fix(Player.PosX), Fix(Player.PosY), Fix(Player.PosX + Cos(Player.Radians) * 30), Fix(Player.PosY + Sin(Player.Radians) * 30)
Picture1.Width = PosX
Picture1.Height = PosY
End Sub```
bonus:
Code:
```'better than Line() method... don't use the MoveToEx() and LineTo() API functions...
'they work on IDE but not on exe:
Private Type POINTAPI
x As Long
y As Long
End Type
Private Declare Function Polyline Lib "gdi32" (ByVal hdc As Long, lpPoint As POINTAPI, ByVal nCount As Long) As Long
Private Sub DrawLine(hdc As Long, X0 As Long, Y0 As Long, X1 As Long, Y1 As Long)
Dim s(2) As POINTAPI
s(0).x = X0
s(0).y = Y0
s(1).x = X1
s(1).y = Y1
Polyline hdc, s(0), 2
End Sub```

9. ## Re: using arrays, can i speed up my for loop?

heres my entire code:
Code:
```Option Explicit

Private Type POINTAPI
x As Long
y As Long
End Type
Private Declare Function Polyline Lib "gdi32" (ByVal hdc As Long, lpPoint As POINTAPI, ByVal nCount As Long) As Long

Private Declare Function Rectangle Lib "gdi32" (ByVal hdc As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function Ellipse Lib "gdi32" (ByVal hdc As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function GetTickCount Lib "kernel32" () As Long

Private Type Character
PosX As Double
PosY As Double
MapX As Integer
MapY As Integer
MoveX As Double
MoveY As Double
End Type

Dim Player As Character

Dim FrameCount As Integer
Dim FramePerSecond As Integer
Dim OldTime As Long
Dim ActualTime As Long
Dim blnLoop As Boolean
Dim LevelMap0(10) As Variant

Private Sub DrawLine(hdc As Long, X0 As Long, Y0 As Long, X1 As Long, Y1 As Long)
Dim s(2) As POINTAPI
s(0).x = X0
s(0).y = Y0
s(1).x = X1
s(1).y = Y1
Polyline hdc, s(0), 2
End Sub

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
Const Speed As Integer = 2
Const Radians As Double = 0.2
If (KeyCode = vbKeyEscape) Then
blnLoop = False
End
ElseIf (KeyCode = vbKeyLeft) Then
ElseIf (KeyCode = vbKeyRight) Then
ElseIf (KeyCode = vbKeyUp) Then
Player.PosX = Player.PosX + Player.MoveX
Player.PosY = Player.PosY + Player.MoveY
Player.MapX = Fix((Player.PosX) / 33)
Player.MapY = Fix((Player.PosY) / 33)
ElseIf (KeyCode = vbKeyDown) Then
Player.PosX = Player.PosX - Player.MoveX
Player.PosY = Player.PosY - Player.MoveY
Player.MapX = Fix((Player.PosX) / 33)
Player.MapY = Fix((Player.PosY) / 33)
End If
Me.Caption = "X: " + Str(Player.MapX) + "  Y: " + Str(Player.MapY) + " FPS: " + Str(FramePerSecond)
End Sub

Private Sub DrawMap()
Dim x As Integer
Dim y As Integer
Dim PosX As Integer
Dim PosY As Integer
Dim col As ColorConstants

PosX = 0
PosY = 0
For y = 0 To 9
For x = 0 To 9
col = LevelMap0(y)(x)
Picture1.FillColor = col
Rectangle Picture1.hdc, PosX, PosY, PosX + 33, PosY + 33
PosX = PosX + 33
Next
If ((PosY / 33) < 9) Then PosX = 0
PosY = PosY + 33
Next

Picture1.FillColor = vbYellow
Ellipse Picture1.hdc, Player.PosX - 4, Player.PosY - 4, Player.PosX + 4, Player.PosY + 4
DrawLine Picture1.hdc, Fix(Player.PosX), Fix(Player.PosY), Fix(Player.PosX + Cos(Player.Radians) * 30), Fix(Player.PosY + Sin(Player.Radians) * 30)
Picture1.Width = PosX
Picture1.Height = PosY
End Sub

LevelMap0(0) = Array(vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue)
LevelMap0(1) = Array(vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue)
LevelMap0(2) = Array(vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue)
LevelMap0(3) = Array(vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue)
LevelMap0(4) = Array(vbBlue, vbWhite, vbWhite, vbBlue, vbBlue, vbBlue, vbWhite, vbWhite, vbWhite, vbBlue)
LevelMap0(5) = Array(vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue, vbWhite, vbBlue)
LevelMap0(6) = Array(vbBlue, vbWhite, vbWhite, vbBlue, vbBlue, vbBlue, vbWhite, vbWhite, vbWhite, vbBlue)
LevelMap0(7) = Array(vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue)
LevelMap0(8) = Array(vbBlue, vbWhite, vbWhite, vbWhite, vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue)
LevelMap0(9) = Array(vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue)
Player.PosX = 100
Player.PosY = 100
blnLoop = True
Player.MapX = Fix((Player.PosX - 10) / 33)
Player.MapY = Fix((Player.PosY - 10) / 33)
Me.Caption = "X: " + Str(Player.MapX) + "  Y: " + Str(Player.MapY) + " FPS: " + Str(FramePerSecond)
Me.Show
FrameCount = 0
FramePerSecond = 0
OldTime = GetTickCount()
Dim Second As Long
Do While (blnLoop = True)
Picture1.Cls
DrawMap
Me.Picture = Picture1.Image
FrameCount = FrameCount + 1
ActualTime = GetTickCount()
Second = ActualTime - OldTime
If (Second >= 1000) Then
FramePerSecond = FrameCount
FrameCount = 0
Me.Caption = "X: " + Str(Player.MapX) + "  Y: " + Str(Player.MapY) + " FPS: " + Str(FramePerSecond)
OldTime = GetTickCount()
End If
DoEvents
Loop
End Sub```
i have more or less 500 FPS... seems not good performance, but i don't know what i can do more

10. ## Re: using arrays and can i speed up my for loop?

As wqweto suggested:

Code:
```
Dim x As Variant
Dim y As Variant
Dim col As ColorConstants

For Each y In LevelMap0
For Each x In y
col = x     ' This assignment isn't really necessary.  Just use x.

Next
Next

```
I'd still probably convert it all to a Long 2D array, and turn off array-bounds-checks, which I still think would be faster yet.

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

EDIT (CAUTION): You've got LevelMap0 dimmed to 10, whereas it should be 9. For the "For Each" to work correctly, you need to get this correct. You're letting your C programming influence your VB6 programming.

11. ## Re: using arrays and can i speed up my for loop?

Code:
```Private Sub DrawMap(ByRef Pic As PictureBox)
Dim PosX As Integer
Dim PosY As Integer
Dim x As Variant
Dim y As Variant
Dim col As ColorConstants

PosX = 0
PosY = 0
For Each y In LevelMap0
For Each x In y
col = x     ' This assignment isn't really necessary.  Just use x.
Pic.FillColor = col
Rectangle Pic.HDC, PosX, PosY, PosX + 33, PosY + 33
PosX = PosX + 33
Next
If ((PosY / 33) < 9) Then PosX = 0
PosY = PosY + 33
Next
Pic.FillColor = vbYellow
Ellipse Pic.HDC, Player.PosX - 4, Player.PosY - 4, Player.PosX + 4, Player.PosY + 4
DrawLine Pic.HDC, Player.PosX + 0, Player.PosY + 0, Player.PosX + Cos(Player.Radians) * 30, Player.PosY + Sin(Player.Radians) * 30

Pic.Width = PosX
Pic.Height = PosY
End Sub```
i just did, but i get an error: "run-time error '13': type mismatch"
on:
Code:
`For Each x In y`

12. ## Re: using arrays and can i speed up my for loop?

u know u can use stretctblt to create rectangles and lines?
by using a 1x1 pixel with the desired color u can stretch it into rectangles/squares/lines

what I mean is
U have a memoryhdc where u "add" pixels. like a red dot at 0/0 position
now u can use stretchblt to copy that 0/0 (width/height 1/1) into whatever size
that way u dont need to assign color, u just use the "position" where u created the dot.

so u can do 0/0 red, 1/0 white 2/0 blue etc
and use that dot to make that shape.

13. ## Re: using arrays and can i speed up my for loop?

so i must go back?????
the variable is 'variant' for i use the array()
is more easy:
Code:
```LevelMap0(0) = Array(vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue)
LevelMap0(1) = Array(vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue)
LevelMap0(2) = Array(vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue)
LevelMap0(3) = Array(vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue)
LevelMap0(4) = Array(vbBlue, vbWhite, vbWhite, vbBlue, vbBlue, vbBlue, vbWhite, vbWhite, vbWhite, vbBlue)
LevelMap0(5) = Array(vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue, vbWhite, vbBlue)
LevelMap0(6) = Array(vbBlue, vbWhite, vbWhite, vbBlue, vbBlue, vbBlue, vbWhite, vbWhite, vbWhite, vbBlue)
LevelMap0(7) = Array(vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue)
LevelMap0(8) = Array(vbBlue, vbWhite, vbWhite, vbWhite, vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue)
LevelMap0(9) = Array(vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue)```
than:
Code:
`]LevelMap0(0)(0) = vbBlue`

14. ## Re: using arrays and can i speed up my for loop?

Just convert the array to long, you can do it like this:
Code:
```Dim LevelMap0(10, 10) As Long

Private Sub InitMap(ByVal row As Long, aData)
Dim i As Long
Next
End Sub

InitMap 0, Array(vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue)
InitMap 1, Array(vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue)
'etc
End Sub```

15. ## Re: using arrays and can i speed up my for loop?

i just did, but same error message in same line:
Code:
```Dim LevelMap0(10, 10) As Long

Private Sub InitMap(ByVal row As Long, aData)
Dim i As Long
Next
End Sub

Private Sub DrawMap(ByRef pic As PictureBox)
Dim x As Variant
Dim y As Variant
Dim PosX As Integer
Dim PosY As Integer

PosX = 0
PosY = 0

Dim col As ColorConstants

For Each y In LevelMap0
For Each x In y 'error message here on type mismatch
col = x     ' This assignment isn't really necessary.  Just use x.

pic.FillColor = col
Rectangle pic.HDC, PosX, PosY, PosX + 33, PosY + 33
PosX = PosX + 33
Next
If ((PosY / 33) < 9) Then PosX = 0
PosY = PosY + 33
Next

pic.FillColor = vbYellow
Ellipse pic.HDC, Player.PosX - 4, Player.PosY - 4, Player.PosX + 4, Player.PosY + 4
DrawLine pic.HDC, Fix(Player.PosX), Fix(Player.PosY), Fix(Player.PosX + Cos(Player.Radians) * 30), Fix(Player.PosY + Sin(Player.Radians) * 30)
pic.Width = PosX
pic.Height = PosY
End Sub

InitMap 0, Array(vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue)
InitMap 1, Array(vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue)
InitMap 2, Array(vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue)
InitMap 3, Array(vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue)
InitMap 4, Array(vbBlue, vbWhite, vbWhite, vbBlue, vbBlue, vbBlue, vbWhite, vbWhite, vbWhite, vbBlue)
InitMap 5, Array(vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue, vbWhite, vbBlue)
InitMap 6, Array(vbBlue, vbWhite, vbWhite, vbBlue, vbBlue, vbBlue, vbWhite, vbWhite, vbWhite, vbBlue)
InitMap 7, Array(vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue)
InitMap 8, Array(vbBlue, vbWhite, vbWhite, vbWhite, vbBlue, vbWhite, vbWhite, vbWhite, vbWhite, vbBlue)
InitMap 9, Array(vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue, vbBlue)
Player.PosX = 100```

16. ## Re: using arrays and can i speed up my for loop?

Don't use for each
Code:
```Private Sub DrawMap(ByRef pic As PictureBox)
Dim x As Long
Dim y As Long
Dim PosX As Integer
Dim PosY As Integer

PosX = 0
PosY = 0

Dim col As ColorConstants

For y = 0 To 9
For x = 0 To 9
pic.FillColor = LevelMap0(y, x)```

17. ## Re: using arrays and can i speed up my for loop?

And you should also consider baka's advice - do the drawing on a memorydc and only after the bitmap is ready - copy it to the window, using BitBlt.
It is faster, and more smooth (no flickering)
Also, don't use FillColor.
Use DC_BRUSH and SetDCBrushColor.

18. ## Re: using arrays and can i speed up my for loop?

ok... i will create an image class for it
if is much more faster, i will test it. thanks

19. ## Re: using arrays and can i speed up my for loop?

how can i add the variable name on parameter on the function?
Code:
```Private Sub InitMap(byval ParamArray map(), ByVal row As Long, aData)
Dim i As Long
Next
End Sub```
i'm doing wrong
but no success

20. ## Re: using arrays and can i speed up my for loop?

Code:
```Private Sub InitMap(map() As Long, ByVal row As Long, aData)
Dim i As Long
Next
End Sub```

21. ## Re: using arrays and can i speed up my for loop?

thanks for all

22. ## Re: using arrays and can i speed up my for loop?

to give u some "start"

Code:
```Sub CreateSurface(ByVal Width, ByVal Height)
.biPlanes = 1
.biBitCount = 32
.biWidth = Width
.biHeight = -Height
.biSizeImage = Width * Height * 4
End With
With Surface
If .hDC > 0 Then
SelectObject .hDC, .orgDIB
DeleteObject .DIB
DeleteDC .hDC
End If
.Width = Width
.Height = Height
.hDC = CreateCompatibleDC(0)
.DIB = CreateDIBSection(.hDC, DIBHeader, 0, .Pointer, .Handle, 0)
.orgDIB = SelectObject(.hDC, .DIB)
SetBkMode .hDC, 1
End With
End Sub```
this little code will create an "empty" 32bit surface that u can use to draw into.
its 32bit so u have opacity as well.

23. ## Re: using arrays and can i speed up my for loop?

Originally Posted by Elroy
I'd still probably convert it all to a Long 2D array, and turn off array-bounds-checks, which I still think would be faster yet.
It would be interesting to test if using Variants would be faster than checking whether the indexes are within bounds...

24. ## Re: using arrays and can i speed up my for loop?

my image class:
Code:
```Option Explicit

Private Type POINTAPI
x As Long
y As Long
End Type
Private Declare Function Polyline Lib "gdi32" (ByVal HDC As Long, lpPoint As POINTAPI, ByVal nCount As Long) As Long

Private Declare Function Ellipse Lib "gdi32.dll" (ByVal HDC As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal HDC As Long) As Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal HDC As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal HDC As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal HDC As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function Rectangle Lib "gdi32" (ByVal HDC As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function BitBlt Lib "gdi32.dll" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Private Const SRCCOPY = &HCC0020

'Declarando variÃ¡veis

Public HDC As Long
Public hbm As Long
Public hbmOld As Long
Public ImageWidth As Long
Public ImageHeight As Long

Public Sub DrawLine(X0 As Long, Y0 As Long, X1 As Long, Y1 As Long)
Dim s(2) As POINTAPI
s(0).x = X0
s(0).y = Y0
s(1).x = X1
s(1).y = Y1
Polyline HDC, s(0), 2
End Sub

Public Sub DrawCircle(X1 As Long, Y1 As Long, X2 As Long, Y2 As Long)
Ellipse HDC, X1, Y1, X2, Y2
End Sub

Public Sub DrawRectangle(X0 As Long, Y0 As Long, X1 As Long, Y1 As Long)
Rectangle HDC, X0, Y0, X1, Y1
End Sub

Public Sub NewImage(Width As Long, Height As Long)

HDC = CreateCompatibleDC(0)

'Criar HBitmap
hbm = CreateCompatibleBitmap(HDC, Width, Height)
hbmOld = SelectObject(HDC, hbm)
ImageWidth = Width
ImageHeight = Height
End Sub

Public Sub Draw(HDCDestination As Long, PosX As Long, PosY As Long)
BitBlt HDCDestination, PosX, PosY, ImageWidth, ImageHeight, HDC, 0, 0, SRCCOPY
End Sub

Public Sub DeleteImage()
'Limpar memÃ³ria
SelectObject HDC, hbmOld
DeleteObject hbm
DeleteDC HDC
End Sub```
Code:
```Dim s As Image
Set s = New Image
s.NewImage 500, 500

Do While (blnLoop = True)
'Me.Cls
DrawMap
s.Draw Me.HDC, 0, 0
...................```
Code:
```Private Sub DrawMap()
Dim x As Integer
Dim y As Integer
Dim PosX As Integer
Dim PosY As Integer

PosX = 0
PosY = 0

Dim col As ColorConstants

For y = 0 To 9
For x = 0 To 9
'pic.FillColor = LevelMap0(y, x)
'Rectangle HDC, PosX, PosY, PosX + 33, PosY + 33
s.DrawRectangle CLng(PosX), CLng(PosY), CLng(PosX + 33), CLng(PosY + 33)
PosX = PosX + 33
Next
If ((PosY / 33) < 9) Then PosX = 0
PosY = PosY + 33
Next

'pic.FillColor = vbYellow
'Ellipse HDC, Player.PosX - 4, Player.PosY - 4, Player.PosX + 4, Player.PosY + 4
s.DrawCircle Player.PosX - 4, Player.PosY - 4, Player.PosX + 4, Player.PosY + 4
s.DrawLine Fix(Player.PosX), Fix(Player.PosY), Fix(Player.PosX + Cos(Player.Radians) * 30), Fix(Player.PosY + Sin(Player.Radians) * 30)
End Sub```
instead 500, now i have more or less 800FPS
PS: AutoRedraw property is false!!!!

25. ## Re: using arrays and can i speed up my for loop?

in these case: the DIB's is more faster or the same?

26. ## Re: using arrays and can i speed up my for loop?

But you drop out the color?

27. ## Re: using arrays and can i speed up my for loop?

i know there isn't a color, for now... i must update the rectangle function

28. ## Re: using arrays and can i speed up my for loop?

Originally Posted by joaquim
in these case: the DIB's is more faster or the same?
My guess is the difference is insignificant.
But why guess? Try and tell us the definitive answer!

29. ## Re: using arrays and can i speed up my for loop?

Re-post of sections of my post #10:

Code:
```
Dim x As Variant
Dim y As Variant
Dim col As ColorConstants

For Each y In LevelMap0
For Each x In y
col = x     ' This assignment isn't really necessary.  Just use x.

Next
Next

```
I'd still probably convert it all to a Long 2D array, and turn off array-bounds-checks, which I still think would be faster yet.

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

Also, you've got LevelMap0 dimmed to 10, whereas it should be 9. For the "For Each" to work correctly, you need to get this correct.

30. ## Re: using arrays and can i speed up my for loop?

The fact that "For Each" circumvents any bounds checking is definitely going to provide some speedup.

Also, using Variants isn't a huge deal. The only slowdown is, when using, checking the Variant's type from the first two bytes of it.

Also, I didn't want to confuse things in the above, but you can also enumerate Variant arrays with a specific type, so long as you're sure all the Variant items match that type. For example:

Code:
```
Dim y As Variant
Dim col As Long

For Each y In LevelMap0
For Each col In y

Next
Next

```
Done that way, the color goes directly into col as part of the loop. Then, when col is used, there won't be any Variant type checking.

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

And yes, a speed-test between a "For Each" approach compared to a "For i" approach with bounds checking remaining on, would be interesting. There's no doubt in my mind though that a "For i" with bounds checking off has to be the fastest.

31. ## Re: using arrays and can i speed up my for loop?

Elroy: the mismatch type error continues with that code

i need a correction... these HDC\bitmap is created, but it's Black and white?
Code:
```Public Sub NewImage(Width As Long, Height As Long)

HDC = CreateCompatibleDC(0)
'Criar HBitmap
hbm = CreateCompatibleBitmap(HDC, Width, Height)
hbmOld = SelectObject(HDC, hbm)
ImageWidth = Width
ImageHeight = Height
End Sub```
i don't remember correctly but the CreateCompatibleBitmap() is give me a black and white Bitmap?

32. ## Re: using arrays and can i speed up my for loop?

It depends what hDC you use for CreateCompatibleBitmap. If you want a full color one you need to get another hDC, like this:

Code:
```hDCDesktop = GetDC(0)
hDC = CreateCompatibleDC(hDCDesktop)
hDCDesktop = ReleaseDC(hDCDesktop)```

33. ## Re: using arrays and can i speed up my for loop?

i did.. but the same problem

34. ## Re: using arrays and can i speed up my for loop?

finally it's fixed:
Code:
```Public Sub NewImage(Width As Long, Height As Long)
'Creating HDC:
hdc = CreateCompatibleDC(0)

'Creating a Bitmap with full color(planes are 1 and the bits are 32):
hbm = CreateBitmap(Width, Height, 1, 32, ByVal 0) 'Byval 0 is for don't use\get the pixels array

'select the Bitmap to HDC:
hbmOld = SelectObject(hdc, hbm)

ImageWidth = Width
ImageHeight = Height
End Sub```
is best use the CreateBitmap() instead CreateCompatibleBitmap()... and i can use full color

35. ## Re: using arrays and can i speed up my for loop?

i have almost 600FPS... only for draw the map

36. ## Re: using arrays and can i speed up my for loop?

Originally Posted by Elroy
The fact that "For Each" circumvents any bounds checking is definitely going to provide some speedup.

Also, using Variants isn't a huge deal. The only slowdown is, when using, checking the Variant's type from the first two bytes of it.

Also, I didn't want to confuse things in the above, but you can also enumerate Variant arrays with a specific type, so long as you're sure all the Variant items match that type.
This may be a dumb question but how exactly does "For Each" know to advance to the next element in the enumeration if it doesn't check the total number of elements the same as "For i = LBound To UBound"?

37. ## Re: using arrays and can i speed up my for loop?

Originally Posted by VanGoghGaming
This may be a dumb question but how exactly does "For Each" know to advance to the next element in the enumeration if it doesn't check the total number of elements the same as "For i = LBound To UBound"?
You get bounds check on array item access i.e. in clr = LevelMap0(y)(x) you get checks on red and second time on blue codegen. Instead of some single CPU instruction pointer dereference you get L/UBounds retrieval from the SAFEARRAY + actual checks done inside a function call.

It's not the bounds on the For loop which are the performance problem.

cheers,
</wqw>

38. ## Re: using arrays and can i speed up my for loop?

Ah, I see now, the problem is the constant lookup in the SAFEARRAY structure. The compiler doesn't know when it's inside a "For" loop where the indexes are pretty much guaranteed to always be within bounds, guess that would be too much to ask.

To be honest I've always been on the fence whether to enable the bounds check optimization or not. Inside "For" loops it's utterly redundant but on the other hand it's very useful to catch errors in other places where you'd never think they could pop up...

39. ## Re: using arrays and can i speed up my for loop?

Originally Posted by VanGoghGaming
Inside "For" loops it's utterly redundant but on the other hand it's very useful to catch errors in other places where you'd never think they could pop up...
Absolutely, I "suffer" For loops degraded performance in all my projects and never disable bounds checks which saved my bacon numerous times.

Of course TB has [ ArrayBoundsChecks (False) ] attribute per functions/modules, not on the whole project only, so future looks good.

cheers,
</wqw>

40. ## Re: using arrays and can i speed up my for loop?

Originally Posted by Elroy
Also, I didn't want to confuse things in the above, but you can also enumerate Variant arrays with a specific type, so long as you're sure all the Variant items match that type. For example:

Code:
```
Dim y As Variant
Dim col As Long

For Each y In LevelMap0
For Each col In y

Next
Next

```
Done that way, the color goes directly into col as part of the loop. Then, when col is used, there won't be any Variant type checking.
That doesn't seem to be working. I get a compiler error:

"For Each control variable must be Variant or Object"

However, it seems that you can enumerate an array of Longs using a Variant control variable. I'll try some performance testing. Nope, still slower than regular index enumeration. It may be worth it for arrays of variants but that is a bad idea in and of itself, if it can be avoided.

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•