-
Jul 16th, 2019, 09:33 PM
#1
Thread Starter
Member
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
-
Jul 16th, 2019, 10:00 PM
#2
Re: Fast clear an array
For clearing arrays, use Erase.
-
Jul 16th, 2019, 10:07 PM
#3
Thread Starter
Member
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!
-
Jul 16th, 2019, 10:11 PM
#4
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.
-
Jul 16th, 2019, 10:38 PM
#5
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.
-
Jul 17th, 2019, 05:54 AM
#6
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.
-
Jul 17th, 2019, 08:01 AM
#7
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.
-
Jul 17th, 2019, 09:58 AM
#8
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.
-
Jul 17th, 2019, 11:27 AM
#9
Re: Fast clear an array
Originally Posted by Elroy
...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.
-
Jul 18th, 2019, 01:55 PM
#10
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
-
Jul 18th, 2019, 03:00 PM
#11
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.
-
Jul 18th, 2019, 08:01 PM
#12
Thread Starter
Member
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!
-
Jul 19th, 2019, 06:03 AM
#13
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.
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|