• Welcome to Valhalla Legends Archive.
 

Remove Array() by index

Started by CrAz3D, March 22, 2004, 01:47 PM

Previous topic - Next topic

Eli_1

#15
assumes:
Filters() = your filter list
removing = string you want to remove


dim tmp() as string

redim tmp(0)
   
for i = 0 to ubound(filters)
   if lcase(filters(i)) <> lcase(removing) and filters(i) <> "" then
       tmp(ubound(tmp)) = filters(i)
       redim preserve tmp(ubound(tmp) + 1)
   end if
next i

redim preserve tmp(ubound(tmp) - 1)
redim filters(ubound(filters) - 1)

filters = tmp


This is just something I typed up real fast, so there's bound to be an error somewhere, or it might not work at all  ;)

[edit 1] fixed code tags
[edit 2] fixed code typos

CrAz3D

That's basically what I ended up doing, it wokrs fine now.  Thanks
rebundance - having or being in excess of sheer stupidity
(ré-bun-dance)
Quote from: Spht on June 22, 2004, 07:32 PMSlap.
Quote from: Adron on January 28, 2005, 09:17 AMIn a way, I believe that religion is inherently evil, which includes Christianity. I'd also say Christianity is eviller than Buddhism (has more potential for evil).
Quote from: iago on April 19, 2005, 01:06 PM
CrAz3D's ... is too big vertically, at least, too big with ... iago ...

Eli_1


Adron

I did a small test of the laziest possible coding. In this test, a collection is more than 20 times faster than an array.

Command1: 0.5 seconds data generation
Command2: 49 seconds for an array
Command3: 2.2 seconds for a collection


Option Explicit

Dim testdata(100000) As String
Dim removedata(1000) As String

Private Sub swap(a As String, b As String)
 Dim tmp As String
 tmp = a
 a = b
 b = tmp
End Sub

Private Sub Command1_Click()
 Dim t
 t = Timer
 Dim i As Long
 For i = 0 To 100000
   testdata(i) = i
 Next i
 For i = 0 To 100000
   swap testdata(i), testdata(Rnd * 100000)
 Next i
 For i = 0 To 1000
   removedata(i) = testdata(Fix(Rnd * 100) * 1000 + i)
 Next i
 MsgBox Timer - t
End Sub

Private Sub Command2_Click()
 Dim t
 t = Timer
 Dim ar() As String
 Dim i As Long, j As Long, k As Long
 For i = 0 To 100000
   ReDim Preserve ar(i) As String
   ar(i) = testdata(i)
 Next i
 For i = 0 To 1000
   For j = 0 To UBound(ar)
     If ar(j) = removedata(i) Then
       For k = j To UBound(ar) - 1
         ar(k) = ar(k + 1)
       Next k
       Exit For
     End If
   Next j
 Next i
 MsgBox Timer - t
End Sub

Private Sub Command3_Click()
 Dim t
 t = Timer
 Dim i As Long
 Dim co As New Collection
 For i = 0 To 100000
   co.Add testdata(i), testdata(i)
 Next i
 For i = 0 To 1000
   co.Remove removedata(i)
 Next i
 MsgBox Timer - t
End Sub

CrAz3D

Well, now that I am utterly confused on which to use I'll just ask for more opinions.  Any?
rebundance - having or being in excess of sheer stupidity
(ré-bun-dance)
Quote from: Spht on June 22, 2004, 07:32 PMSlap.
Quote from: Adron on January 28, 2005, 09:17 AMIn a way, I believe that religion is inherently evil, which includes Christianity. I'd also say Christianity is eviller than Buddhism (has more potential for evil).
Quote from: iago on April 19, 2005, 01:06 PM
CrAz3D's ... is too big vertically, at least, too big with ... iago ...

Grok

Quote from: CrAz3D on March 23, 2004, 07:16 PM
Well, now that I am utterly confused on which to use I'll just ask for more opinions.  Any?

You have just read the results of an actual test, and you ask for opinions?  Either verify the test yourself or find refuting evidence.  Other opinions are useless in the face of evidence.

CrAz3D

Quote from: Grok on March 23, 2004, 10:10 PM
Quote from: CrAz3D on March 23, 2004, 07:16 PM
Well, now that I am utterly confused on which to use I'll just ask for more opinions.  Any?

You have just read the results of an actual test, and you ask for opinions?  Either verify the test yourself or find refuting evidence.  Other opinions are useless in the face of evidence.
From what I read in about posted links it said that arrays were more effective.
rebundance - having or being in excess of sheer stupidity
(ré-bun-dance)
Quote from: Spht on June 22, 2004, 07:32 PMSlap.
Quote from: Adron on January 28, 2005, 09:17 AMIn a way, I believe that religion is inherently evil, which includes Christianity. I'd also say Christianity is eviller than Buddhism (has more potential for evil).
Quote from: iago on April 19, 2005, 01:06 PM
CrAz3D's ... is too big vertically, at least, too big with ... iago ...

Adron

Quote from: CrAz3D on March 23, 2004, 10:22 PM
From what I read in about posted links it said that arrays were more effective.

The answer is that neither is more effective always, it depends on what you want to do. If you need to find an item and then remove it from the middle (which seemed to be what this question was about) then using a collection may be more effective. Of course, simple optimizations such as reordering the array instead of moving all items up, not rediming it all the time etc may make an array faster.

I chose to use code like that which has been posted here in this thread for the array, and the simplest possible code for the collection.

drivehappy

What is a collection, I've always used arrays within VB. Are they much like linked lists?

Adron

Quote from: drivehappy on March 24, 2004, 11:30 AM
What is a collection, I've always used arrays within VB. Are they much like linked lists?

I don't know how they are really implemented. They look to me like a c++ map<string, void*>. They are probably good at things that linked lists are good at, but also at looking up items from a string. They have a higher overhead than arrays. I think that a VB array is treated as a native data structure that the compiler can optimize while accessing a collection always means making a function call.

o.OV

#25
Started new project
copy and pasted code
placed 4 command buttons on form
compiled into executable
ran executable
clicked in order..

command_1 1.097656
command_2 108.5273
command_3 42.46094
command_4 16.5

My results came out differently..
Is there something else I have to add to the project?

command_4 is just my version of command_2



Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)

Private Sub Command4_Click()
 
   Dim t As Long
   Dim i As Long
   Dim j As Long
   Dim P As Long
   Dim C As Long
   
   Dim TEMPdata() As String
 
   t = Timer
   
   For i = 0 To 100000
       ReDim Preserve TEMPdata(i) As String
       TEMPdata(i) = testdata(i)
   Next i
   
   For i = 0 To 1000
       P = UBound(TEMPdata)
       For j = 0 To P
           If removedata(i) = TEMPdata(j) Then
               C = StrPtr(TEMPdata(P))
               CopyMemory ByVal VarPtr(TEMPdata(P)), ByVal VarPtr(TEMPdata(j)), 4
               CopyMemory ByVal VarPtr(TEMPdata(j)), C, 4
               ReDim Preserve TEMPdata(P - 1) As String
               Exit For
           End If
       Next j
   Next i
   
   MsgBox Timer - t
 
End Sub



Add-On:
I was expecting command_3 to take less then 10 seconds. Any ideas?
If the facts don't fit the theory, change the facts. - Albert Einstein

Adron

Quote from: o.OV on March 24, 2004, 01:23 PM
Started new project
copy and pasted code
placed 4 command buttons on form
compiled into executable
ran executable
clicked in order..

command_1 1.097656
command_2 108.5273
command_3 42.46094
command_4 16.5

My results came out differently..
Is there something else I have to add to the project?

No, I just verified it, trying it in both vb5 and vb6 and with p-code and native code. Native code cuts my array time down to ~30 seconds, and collection code to around 1.8 seconds. Command3 never reaches 3 seconds.

The collection seems to use about twice as much memory. Perhaps you're low on memory?

o.OV

#27
Yea.. maybe low memory.
196 megabytes of memory is considered
inadequate by most. heh  ;D
and my processor is a 500mhz amd

Add-On:
And I did reboot before running.
I had at least 75 megabytes
of physical memory available at run time.

If memory really is a problem..
I am better off with a simple array.
But I want to test this collection thing anyways.
I'm gonna go and cut the array sizes down
and see if that helps.
If the facts don't fit the theory, change the facts. - Albert Einstein

o.OV

#28
Adron, I need you to confirm that my changes were made correctly.

list of changes:
Timer is now GetTickCount
100000 is now 1000
command_1 has been modified



Option Explicit

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
Private Declare Function GetTickCount Lib "kernel32" () As Long

Dim testdata(1000) As String
Dim removedata(1000) As String

Private Sub swap(a As String, b As String)
 Dim tmp As String
 tmp = a
 a = b
 b = tmp
End Sub

Private Sub Command1_Click()
 Dim t
 t = GetTickCount
 Dim i As Long
 For i = 0 To 1000
   testdata(i) = i
   removedata(i) = i
 Next i
 For i = 0 To 1000
   swap testdata(i), testdata(Rnd * 1000)
   swap removedata(i), removedata(Rnd * 1000)
 Next i
 MsgBox GetTickCount - t
End Sub

Private Sub Command2_Click()
 Dim t
 t = GetTickCount
 Dim ar() As String
 Dim i As Long, j As Long, k As Long
 For i = 0 To 1000
   ReDim Preserve ar(i) As String
   ar(i) = testdata(i)
 Next i
 For i = 0 To 1000
   For j = 0 To UBound(ar)
     If ar(j) = removedata(i) Then
       For k = j To UBound(ar) - 1
         ar(k) = ar(k + 1)
       Next k
       Exit For
     End If
   Next j
 Next i
 MsgBox GetTickCount - t
End Sub

Private Sub Command3_Click()
 Dim t
 t = GetTickCount
 Dim i As Long
 Dim co As New Collection
 For i = 0 To 1000
   co.Add testdata(i), testdata(i)
 Next i
 For i = 0 To 1000
   co.Remove removedata(i)
 Next i
 MsgBox GetTickCount - t
End Sub

Private Sub Command4_Click()
 
   Dim t As Long
   Dim i As Long
   Dim j As Long
   Dim P As Long
   Dim C As Long
   
   Dim TEMPdata() As String
 
   t = GetTickCount
   
   For i = 0 To 1000
       ReDim Preserve TEMPdata(i + 1) As String
       TEMPdata(i) = testdata(i)
   Next i
   For i = 0 To 1000
       P = UBound(TEMPdata)
       For j = 0 To P
           If removedata(i) = TEMPdata(j) Then
               C = StrPtr(TEMPdata(P))
               CopyMemory ByVal VarPtr(TEMPdata(P)), ByVal VarPtr(TEMPdata(j)), 4
               CopyMemory ByVal VarPtr(TEMPdata(j)), C, 4
               ReDim Preserve TEMPdata(P - 1) As String
               Exit For
           End If
       Next j
   Next i
   
   MsgBox GetTickCount - t
 
End Sub

If the facts don't fit the theory, change the facts. - Albert Einstein

CrAz3D

Private Sub Command1_Click()
 Dim t
 t = Timer
 Dim i As Long
 For i = 0 To 100000
   testdata(i) = i
 Next i
 For i = 0 To 100000
   swap testdata(i), testdata(Rnd * 100000)
 Next i
 For i = 0 To 1000
   removedata(i) = testdata(Fix(Rnd * 100) * 1000 + i)
 Next i
 MsgBox Timer - t
End Sub


I understand what Command2 & 3 are, but what is Command1 exactly?  I read that it is a data generation, but what does a data generation do?
rebundance - having or being in excess of sheer stupidity
(ré-bun-dance)
Quote from: Spht on June 22, 2004, 07:32 PMSlap.
Quote from: Adron on January 28, 2005, 09:17 AMIn a way, I believe that religion is inherently evil, which includes Christianity. I'd also say Christianity is eviller than Buddhism (has more potential for evil).
Quote from: iago on April 19, 2005, 01:06 PM
CrAz3D's ... is too big vertically, at least, too big with ... iago ...

|