Page 1 of 2 12 LastLast
Results 1 to 40 of 57

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

  1. #1

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,856

    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?
    Last edited by joaquim; Dec 3rd, 2023 at 12:59 PM.
    VB6 2D Sprite control

    To live is difficult, but we do it.

  2. #2
    Frenzied Member VanGoghGaming's Avatar
    Join Date
    Jan 2020
    Location
    Eve Online - Mining, Missions & Market Trading!
    Posts
    1,219

    Lightbulb 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. #3
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,625

    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.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  4. #4
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,625

    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.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  5. #5
    Addicted Member
    Join Date
    Jul 2021
    Posts
    163

    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. #6
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,045

    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. #7
    The Idiot
    Join Date
    Dec 2014
    Posts
    2,711

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

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,856

    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
    VB6 2D Sprite control

    To live is difficult, but we do it.

  9. #9

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,856

    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
        Radians 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
            Player.Radians = Player.Radians - Radians
            Player.MoveX = Cos(Player.Radians) * Speed
            Player.MoveY = Sin(Player.Radians) * Speed
        ElseIf (KeyCode = vbKeyRight) Then
            Player.Radians = Player.Radians + Radians
            Player.MoveX = Cos(Player.Radians) * Speed
            Player.MoveY = Sin(Player.Radians) * Speed
        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
    
    Private Sub Form_Load()
        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
        Player.MoveX = Cos(Player.Radians) * 5
        Player.MoveY = Sin(Player.Radians) * 5
        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
    VB6 2D Sprite control

    To live is difficult, but we do it.

  10. #10
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,625

    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.
    Last edited by Elroy; Dec 3rd, 2023 at 01:24 PM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  11. #11

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,856

    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
    Last edited by joaquim; Dec 3rd, 2023 at 01:42 PM.
    VB6 2D Sprite control

    To live is difficult, but we do it.

  12. #12
    The Idiot
    Join Date
    Dec 2014
    Posts
    2,711

    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.
    Last edited by baka; Dec 3rd, 2023 at 02:16 PM.

  13. #13

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,856

    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
    VB6 2D Sprite control

    To live is difficult, but we do it.

  14. #14
    Addicted Member
    Join Date
    Jul 2021
    Posts
    163

    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
        For i = LBound(aData) To UBound(aData)
            LevelMap0(row, i) = aData(i)
        Next
    End Sub
    
    
    Private Sub Form_Load()
        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. #15

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,856

    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
        For i = LBound(aData) To UBound(aData)
            LevelMap0(row, i) = aData(i)
        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
    
    
    Private Sub Form_Load()
        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
    VB6 2D Sprite control

    To live is difficult, but we do it.

  16. #16
    Addicted Member
    Join Date
    Jul 2021
    Posts
    163

    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. #17
    Addicted Member
    Join Date
    Jul 2021
    Posts
    163

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

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,856

    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
    VB6 2D Sprite control

    To live is difficult, but we do it.

  19. #19

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,856

    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
        For i = LBound(aData) To UBound(aData)
            map(row, i) = aData(i)
        Next
    End Sub
    i'm doing wrong
    i tried like before: https://www.vbforums.com/showthread....y-on-parameter
    but no success
    VB6 2D Sprite control

    To live is difficult, but we do it.

  20. #20
    Addicted Member
    Join Date
    Jul 2021
    Posts
    163

    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
        For i = LBound(aData) To UBound(aData)
            map(row, i) = aData(i)
        Next
    End Sub

  21. #21

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,856

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

    thanks for all
    VB6 2D Sprite control

    To live is difficult, but we do it.

  22. #22
    The Idiot
    Join Date
    Dec 2014
    Posts
    2,711

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

    to give u some "start"

    Code:
    Sub CreateSurface(ByVal Width, ByVal Height)
        With DIBHeader
            .biSize = Len(DIBHeader)
            .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. #23
    Frenzied Member VanGoghGaming's Avatar
    Join Date
    Jan 2020
    Location
    Eve Online - Mining, Missions & Market Trading!
    Posts
    1,219

    Lightbulb Re: using arrays and can i speed up my for loop?

    Quote Originally Posted by Elroy View Post
    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. #24

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,856

    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!!!!
    VB6 2D Sprite control

    To live is difficult, but we do it.

  25. #25

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,856

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

    in these case: the DIB's is more faster or the same?
    VB6 2D Sprite control

    To live is difficult, but we do it.

  26. #26
    Addicted Member
    Join Date
    Jul 2021
    Posts
    163

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

    But you drop out the color?

  27. #27

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,856

    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
    VB6 2D Sprite control

    To live is difficult, but we do it.

  28. #28
    Addicted Member
    Join Date
    Jul 2021
    Posts
    163

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

    Quote Originally Posted by joaquim View Post
    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. #29
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,625

    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.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  30. #30
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,625

    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.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  31. #31

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,856

    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?
    VB6 2D Sprite control

    To live is difficult, but we do it.

  32. #32
    Frenzied Member VanGoghGaming's Avatar
    Join Date
    Jan 2020
    Location
    Eve Online - Mining, Missions & Market Trading!
    Posts
    1,219

    Cool 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. #33

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,856

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

    i did.. but the same problem
    VB6 2D Sprite control

    To live is difficult, but we do it.

  34. #34

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,856

    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
    VB6 2D Sprite control

    To live is difficult, but we do it.

  35. #35

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,856

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

    i have almost 600FPS... only for draw the map
    VB6 2D Sprite control

    To live is difficult, but we do it.

  36. #36
    Frenzied Member VanGoghGaming's Avatar
    Join Date
    Jan 2020
    Location
    Eve Online - Mining, Missions & Market Trading!
    Posts
    1,219

    Question Re: using arrays and can i speed up my for loop?

    Quote Originally Posted by Elroy View Post
    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. #37
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,045

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

    Quote Originally Posted by VanGoghGaming View Post
    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. #38
    Frenzied Member VanGoghGaming's Avatar
    Join Date
    Jan 2020
    Location
    Eve Online - Mining, Missions & Market Trading!
    Posts
    1,219

    Thumbs up 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. #39
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,045

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

    Quote Originally Posted by VanGoghGaming View Post
    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. #40
    Frenzied Member VanGoghGaming's Avatar
    Join Date
    Jan 2020
    Location
    Eve Online - Mining, Missions & Market Trading!
    Posts
    1,219

    Post Re: using arrays and can i speed up my for loop?

    Quote Originally Posted by Elroy View Post
    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.

Page 1 of 2 12 LastLast

Posting Permissions

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



Click Here to Expand Forum to Full Width