Results 1 to 13 of 13

Thread: Fast clear an array

  1. #1

    Thread Starter
    Member
    Join Date
    Oct 2018
    Posts
    59

    Fast clear an array

    HI, guys!

    I have one question:
    Code:
    Private Type udtCell
        nAlignment As Integer
        nFormat As Integer
        nFlags As Integer
        sValue As String
        sTag As String
        lCellData As Long
        pPic As StdPicture
        IsSized As Boolean
    End Type
    Private Type udtItem
        lHeight As Long
        lImage As Long
        lItemData As Long
        nFlags As Integer
        sTag As String
        bGroupRow As Boolean
        bVisible As Boolean
        Cell() As udtCell
    End Type
    Private Declare Sub ZeroMemory Lib "kernel32" Alias "RtlZeroMemory" (ByRef Destination As Any, ByVal Length As Long)
    
    Private Sub Command1_Click()
        Dim x() As udtItem, y() As udtItem, z() As udtItem, I As Long, L As Long
        For I = 0 To 100000
            ReDim Preserve x(I) As udtItem
            x(I).bVisible = True
            x(I).lHeight = 42
            x(I).sTag = "Number " & I
            'x(I).Cell.nAlignment = 0
        Next
        L = Timer
        ReDim x(0) As udtItem
        Debug.Print "Using ReDim: " & (Timer - L)
        
        For I = 0 To 100000
            ReDim Preserve y(I) As udtItem
            y(I).bVisible = True
            y(I).lHeight = 42
            y(I).sTag = "Number " & I
            'y(I).Cell.nAlignment = 0
        Next
        L = Timer
        Erase y
        Debug.Print "Using Erase: " & (Timer - L)
        
        For I = 0 To 100000
            ReDim Preserve z(I) As udtItem
            z(I).bVisible = True
            z(I).lHeight = 42
            z(I).sTag = "Number " & I
            'z(I).Cell.nAlignment = 0
        Next
        L = Timer
        'How can I implement ZeroMemory to clear z() array???
    
        ZeroMemory z(0), Ubound(z) + 1 = VB CRASHES!
    
        Debug.Print "Using ZeroMemory: " & (Timer - L)
        
    End Sub
    Last edited by hennyere; Jul 16th, 2019 at 09:41 PM. Reason: comment

  2. #2

  3. #3

    Thread Starter
    Member
    Join Date
    Oct 2018
    Posts
    59

    Re: Fast clear an array

    Hi Eduardo!

    Thank you for your help!

    I have an array with more than 500 thousand elements. Erase does not seem to work well. It takes too long! I think that ZeroMemory is faster!

    Regards!

  4. #4
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: Fast clear an array

    Your mental model of how things work is faulty.

    Lots of data types in VB are not simple blobs of bytes. Object reference types contain a pointer and String references (not fixed-length) also hold a pointer. Variants can also be delicate. Zap those to zeros willy-nilly only at your peril.

  5. #5
    PowerPoster
    Join Date
    Feb 2017
    Posts
    4,995

    Re: Fast clear an array

    Looking again, I see that you are comparing ZeroMemory to Erase.
    Perhaps you could try:

    Code:
    ZeroMemory z(0), 4&
    But Erase does the freeing properly.
    If it is too slow, then you could use variants and store the un-freed arrays in a collection for freeing them later "when you have enough time".

    That would work shomehow as a garbage collector.

  6. #6
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Fast clear an array

    What exactly do you mean by "clearing" the array: removing it from process memory or zeroizing all elements of the array?

    If either of the above, then forget about ZeroMemory. Your UDT contains strings (sTag) and dynamic arrays (Cell). You cannot simply zeroize the pointers without memory leaks or crashes.

    I think you may be mistaken about what ZeroMemory does. It does not remove the memory, it simply writes zeros across the passed range of memory. Erase() will properly deallocate strings, deallocate arrays and their contents, regardless how deep your UDT structure is and finally deallocate the memory blocks used by the array.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  7. #7
    Frenzied Member some1uk03's Avatar
    Join Date
    Jun 2006
    Location
    London, UK
    Posts
    1,663

    Re: Fast clear an array

    Code:
    dim emptyZ() As udtItem
    
    reDim emptyZ(uBound(z))
    
    z = emptyZ
    _____________________________________________________________________

    ----If this post has helped you. Please take time to Rate it.
    ----If you've solved your problem, then please mark it as RESOLVED from Thread Tools.



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

    Re: Fast clear an array

    Yes, as suggested by others, the fact that you've got Strings, Objects, and Dynamic Arrays in your UDTs means that you CAN NOT just set all the UDT memory to zero. That will create a HUGE memory leak, even if it doesn't crash.

    With Erase, you'll be correctly returning all the String memory to Windows, correctly uninstantiating all the objects, and correctly erasing the Dynamic Arrays. Basically, there's no way around this.

    In theory, you could set all your strings to vbNullString, uninstantiate all your objects, and erase all your dynamic arrays before you cleared your UDTs, but I'm not sure you'd be gaining much other than added and unnecessary complexity to your 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.

  9. #9
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Fast clear an array

    Quote Originally Posted by Elroy View Post
    ...but I'm not sure you'd be gaining much other than added and unnecessary complexity to your code.
    I think we should bring up the idea of a recordset or database. With something like a half million items in what appears to be a table-like structure and relationships, recordsets or a database might play well.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  10. #10
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,470

    Re: Fast clear an array

    The easiest way to clear an array is to use dynamic arrays.
    Code:
        Dim bTmp() As Byte
        Dim bArray() As Byte
        ReDim bArray(99)
        'Fill Array
        ReDim bArray(0) 'Clear Array
        'You can use any dimenension, but if you want a NULL array
        bArray = bTmp
    J.A. Coutts

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

    Re: Fast clear an array

    Okay, hennyere, here's something I've done in the past ... create a "blank" version of my UDT, and then use it to zero-out individual elements in my UDT array.

    Using your code, here's an example:

    Code:
    
    Option Explicit
    '
    Private Type udtCell
        nAlignment As Integer
        nFormat As Integer
        nFlags As Integer
        sValue As String
        sTag As String
        lCellData As Long
        pPic As StdPicture
        IsSized As Boolean
    End Type
    Private Type udtItem
        lHeight As Long
        lImage As Long
        lItemData As Long
        nFlags As Integer
        sTag As String
        bGroupRow As Boolean
        bVisible As Boolean
        Cell() As udtCell
    End Type
    '
    
    Private Sub Command1_Click()
        Dim z() As udtItem
        Dim zBlank As udtItem
    
        ReDim z(100)
    
    
    
        ' Do stuff that populates things in your z() array.
    
    
    
        ' And now we wish to delete it.
        Dim i As Long
        For i = LBound(z) To UBound(z)
            z(i) = zBlank
        Next
    
    End Sub
    
    

    Using that approach, you will correctly uninstantiate anything in the StdPicture objects, you will correctly clear any strings in the sTag variables, and you will correctly erase the cell() sub-arrays that may exist.

    I didn't test to see if it's any faster than an Erase z. I'll leave that to you. However, that's about as good as it gets.

    EDIT1: Actually, what couttsj illustrated would also work with your z() array. Basically, when you've got a UDT with pointer-references in it, you can NOT just zero it out. You must let VB6 do it for you, so that those references get correctly handled.

    Now, if your UDT had no references (no strings, no objects, no dynamic arrays, no variants with external data) then you could zero it out.
    Last edited by Elroy; Jul 18th, 2019 at 03:04 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.

  12. #12

    Thread Starter
    Member
    Join Date
    Oct 2018
    Posts
    59

    Re: Fast clear an array

    Hello guys!

    I want to thank everyone for the help!

    What I want is a faster form than "Erase" to memory UDT. Exactly what Erase does, but I thought there was some way faster because Erase is taking about 3 seconds to clear all UDT contents from memory, and that's no good!

    I know that ZeroMemory fills a location in memory with zeros, but I thought so I could clear my UDT. I know I'm wrong.

    I think there is nothing better than Erase, but I believe (or I may be wrong) that Erase in VB5 is faster than VB6. Am I right?

    Is there any way to use VB5 Erase in VB6?

    Thanks for everything!

  13. #13
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Fast clear an array

    The problem is not with Erase() being slow. It is that you are storing items in your array that need to be specially disposed of and those include: stdPicture objects, strings, and SafeArray structures. In addition, with a 1/2 million items that's about 20MB of memory that needs to be be deallocated, just for the items. Once the cells are added, which have strings and stdPicture objects, Erase() will even take longer. Also when using large amounts of memory and you execute ReDim Preserve, you risk heap fragmentation and potential out of memory errors.

    IMO, you should rethink your approach -- possibly looking at a file-based or recrodset/database solution vs. trying to store your entire array in memory. File-based may be too difficult in this specific case? If you are interested in pursuing another approach, ask. Others will surely chime in with recommendations.

    Asking if VB5 functions can be used, is really hiding the problem, not fixing it.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

Tags for this Thread

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