Fastest Selection 
Author Message
 Fastest Selection

I need to rapidly get a token from a string list.
e.g.
Dim sStr as String
Dim sToken as String

sStr = "Orange,Apple,Banna,Pear"   ' this is a stub since the list can be
quite long.
sToken = "22,99,44,33"                  ' matching number of items in each

Both of these are user inputs so I do not immediately control the length of
each item.

Once set, these will not change for the app run.

If the user select Apple then token 99 should be returned.
If Orange, Apple were all the same length then I could get an index from an
Instr calculation, but they can be most any length.
Seems there must be something faster than a For  Next loop of items set in
an array.
yes, VB6
suggestions please



Sun, 11 Mar 2012 07:56:01 GMT  
 Fastest Selection


Quote:
> I need to rapidly get a token from a string list.
> e.g.
> Dim sStr as String
> Dim sToken as String

> sStr = "Orange,Apple,Banna,Pear"   ' this is a stub since the list can
> be quite long.
> sToken = "22,99,44,33"                  ' matching number of items in
> each

> Both of these are user inputs so I do not immediately control the
> length of each item.

> Once set, these will not change for the app run.

> If the user select Apple then token 99 should be returned.
> If Orange, Apple were all the same length then I could get an index
> from an Instr calculation, but they can be most any length.
> Seems there must be something faster than a For  Next loop of items
> set in an array.
> yes, VB6
> suggestions please

Dim strAr() as string
Dim sToken() as string

strAr = Split(sStr, ",")
sToken = Split(sToken, ",")

At this point the string array you want and it's respective token have
the same array element number, so, depending on how you select what the
string is......



Sun, 11 Mar 2012 08:18:51 GMT  
 Fastest Selection


Quote:
> I need to rapidly get a token from a string list.
> e.g.
> Dim sStr as String
> Dim sToken as String

> sStr = "Orange,Apple,Banna,Pear"   ' this is a stub since the list can be
> quite long.
> sToken = "22,99,44,33"                  ' matching number of items in each

> Both of these are user inputs so I do not immediately control the length
> of
> each item.

> Once set, these will not change for the app run.

> If the user select Apple then token 99 should be returned.
> If Orange, Apple were all the same length then I could get an index from
> an
> Instr calculation, but they can be most any length.
> Seems there must be something faster than a For  Next loop of items set in
> an array.
> yes, VB6
> suggestions please

One idea off the top of my head, use a collection and a class module. The
class would have 2 properties, say Name and Token. You'd have one instance
of this class for each pair. Use the name as the key when adding each pair
to the collection. That way, you can have "direct retrieval" of the token.
The class module code might be something like this:

-----BEGIN CODE
Option Explicit

Private m_sItemName     As String
Private m_lToken        As Long

Public Property Let ItemName(ByVal NewValue As String)

    m_sItemName = NewValue

End Property

Public Property Get ItemName() As String

    ItemName = m_sItemName

End Property

Public Property Let Token(ByVal NewValue As Long)

    m_lToken = NewValue

End Property

Public Property Get Token() As Long

    Token = m_lToken

End Property
-----END CODE

Name this class TokenPair (or whatever you want but be sure to change code
below accordingly).

Now, to add instances of this class to the collection (this code in a form
or other module):

-----BEGIN CODE
Option Explicit

Private moTokenPairs            As Collection

Private Sub Form_Load()

    Dim oTokenPair As TokenPair

    Set moTokenPairs = New Collection

    Set oTokenPair = New TokenPair
    With oTokenPair
        .ItemName = "Apple"
        .Token = 99
    End With
    moTokenPairs.Add oTokenPair, oTokenPair.ItemName

    Set oTokenPair = New TokenPair
    With oTokenPair
        .ItemName = "Orange"
        .Token = 22
    End With
    moTokenPairs.Add oTokenPair, oTokenPair.ItemName

    Set oTokenPair = New TokenPair
    With oTokenPair
        .ItemName = "Banana"
        .Token = 44
    End With
    moTokenPairs.Add oTokenPair, oTokenPair.ItemName

    Set oTokenPair = New TokenPair
    With oTokenPair
        .ItemName = "Pear"
        .Token = 33
    End With
    moTokenPairs.Add oTokenPair, oTokenPair.ItemName

End Sub
-----END CODE

Hopefully, you're reading these pairs of values from somewhere and can do
the above in a loop.

Now, to get the token for any of these, just do this (using the correct key
for the item in the collection, of course):

    MsgBox "Token for Apple: " & moTokenPairs("Apple").Token

You could even write a specialized collection class, but it doesn't appear
that'd really be necessary for what you need.  But what you could do with a
specialized collection class would be to have code in its Add method which
checks the collection to make sure a duplicate token and/or name is not
used.  You wouldn't HAVE to have a specialized collection class to do this,
but if you did, you could encapsulate such code within the class.

--
Mike



Sun, 11 Mar 2012 08:55:53 GMT  
 Fastest Selection


Quote:


>> I need to rapidly get a token from a string list.
>> e.g.
>> Dim sStr as String
>> Dim sToken as String

>> sStr = "Orange,Apple,Banna,Pear"   ' this is a stub since the list can
>> be quite long.
>> sToken = "22,99,44,33"                  ' matching number of items in
>> each

>> Both of these are user inputs so I do not immediately control the
>> length of each item.

>> Once set, these will not change for the app run.

>> If the user select Apple then token 99 should be returned.
>> If Orange, Apple were all the same length then I could get an index
>> from an Instr calculation, but they can be most any length.
>> Seems there must be something faster than a For  Next loop of items
>> set in an array.
>> yes, VB6
>> suggestions please

> Dim strAr() as string
> Dim sToken() as string

> strAr = Split(sStr, ",")
> sToken = Split(sToken, ",")

> At this point the string array you want and it's respective token have
> the same array element number, so, depending on how you select what the
> string is......

But I think that's exactly what Lorin's trying to avoid.  If the user types
in Apple in a textbox, you'd have to loop through strAr to get the index to
use for sToken.

One thing that I didn't pay attention to when I replied originally is that
Lorin said if a user "selects" Apple.  Now, does this mean that Apple, Pear,
Orange, etc. will be in a ListBox or ComboBox?  If so, then the token value
can be assigned to each item's ItemData (assuming the token will always be a
Long).

--
Mike



Sun, 11 Mar 2012 09:06:05 GMT  
 Fastest Selection
Copy the string elements in a matching pair of arrays.  Sort the Str array
and shuffle the Token array so that they continue to line up.  When the user
types a name, search the string array using a binary search and return the
corresponding Token item.


Quote:
>I need to rapidly get a token from a string list.
> e.g.
> Dim sStr as String
> Dim sToken as String

> sStr = "Orange,Apple,Banna,Pear"   ' this is a stub since the list can be
> quite long.
> sToken = "22,99,44,33"                  ' matching number of items in each

> Both of these are user inputs so I do not immediately control the length
> of
> each item.

> Once set, these will not change for the app run.

> If the user select Apple then token 99 should be returned.
> If Orange, Apple were all the same length then I could get an index from
> an
> Instr calculation, but they can be most any length.
> Seems there must be something faster than a For  Next loop of items set in
> an array.
> yes, VB6
> suggestions please



Sun, 11 Mar 2012 09:21:46 GMT  
 Fastest Selection


Quote:





>>> I need to rapidly get a token from a string list.
>>> e.g.
>>> Dim sStr as String
>>> Dim sToken as String

>>> sStr = "Orange,Apple,Banna,Pear"   ' this is a stub since the list
>>> can be quite long.
>>> sToken = "22,99,44,33"                  ' matching number of items
>>> in each

>>> Both of these are user inputs so I do not immediately control the
>>> length of each item.

>>> Once set, these will not change for the app run.

>>> If the user select Apple then token 99 should be returned.
>>> If Orange, Apple were all the same length then I could get an index
>>> from an Instr calculation, but they can be most any length.
>>> Seems there must be something faster than a For  Next loop of items
>>> set in an array.
>>> yes, VB6
>>> suggestions please

>> Dim strAr() as string
>> Dim sToken() as string

>> strAr = Split(sStr, ",")
>> sToken = Split(sToken, ",")

>> At this point the string array you want and it's respective token
>> have the same array element number, so, depending on how you select
>> what the string is......

> But I think that's exactly what Lorin's trying to avoid.  If the user
> types in Apple in a textbox, you'd have to loop through strAr to get
> the index to use for sToken.

> One thing that I didn't pay attention to when I replied originally is
> that Lorin said if a user "selects" Apple.  Now, does this mean that
> Apple, Pear, Orange, etc. will be in a ListBox or ComboBox?  If so,
> then the token value can be assigned to each item's ItemData (assuming
> the token will always be a Long).

You are absolutely right......but we won't know until Lorin replies.

Although, how long does it take to look thru an array of strings,
obviously depending on how many, but milliseconds vs. some other method,
like a collection.

1 ms or 20 ms, is there a difference when your waiting for a user to
select something ? Not really.

If the time is insignificant, 1 or 20 ms in my example, go for the most
simple code.

On this PC, I just created an array of 10,000 strings of 8 chars each. It
takes either 30 some or 70 some ms to search the array for one of the
values...in the IDE.

If I'm waiting on a user to somehow pick a value from somewhere, a few 10
of ms delay means little.



Sun, 11 Mar 2012 11:01:02 GMT  
 Fastest Selection


Quote:
> > I need to rapidly get a token from a string list.
> One idea off the top of my head, use a collection and a class module.

Why the class?    List.Add 99, "Apple"   Would suffice.

Although, your second thought, 'How is the user going to select the token'
is right on.   If a list or combo box is going to be used, and the tokens
fit in a Long, then use the ItemData array of the control.

LFS



Sun, 11 Mar 2012 19:57:21 GMT  
 Fastest Selection


Quote:
>I need to rapidly get a token from a string list.
> e.g.
> Dim sStr as String
> Dim sToken as String

> sStr = "Orange,Apple,Banna,Pear"   ' this is a stub since the list can be
> quite long.
> sToken = "22,99,44,33"                  ' matching number of items in each

> Both of these are user inputs so I do not immediately control the length
> of
> each item.

> Once set, these will not change for the app run.

> If the user select Apple then token 99 should be returned.
> If Orange, Apple were all the same length then I could get an index from
> an
> Instr calculation, but they can be most any length.
> Seems there must be something faster than a For  Next loop of items set in
> an array.
> yes, VB6
> suggestions please

Dictionary Object ?


Sun, 11 Mar 2012 21:30:23 GMT  
 Fastest Selection
User entry is all up front and may come from a data file..
I tried these two methods.

Method 1
create two arrays.
loop through the key array and build a  field of max length,
Then Lset each key into it own element and join into a long string
Then later at max program speed, use instr to locate the key.
Calculate the index of the item based on the fixed length of each element.
Use that index into the items to get the value.
Can be used with text or numeric items.

Method II
Just loop through the arrays until a match is found and use the key's index
to get the item at same index.

Results
Both are very fast but the Instr method typically is 20% faster.
After many runs of large loops (10,000) doing a search using both methods it
was unteresting to see that the speed and % difference varied all over the
place probably based on what Windows was up to at the time.

Quote:

> I need to rapidly get a token from a string list.
> e.g.
> Dim sStr as String
> Dim sToken as String

> sStr = "Orange,Apple,Banna,Pear"   ' this is a stub since the list can be
> quite long.
> sToken = "22,99,44,33"                  ' matching number of items in each

> Both of these are user inputs so I do not immediately control the length of
> each item.

> Once set, these will not change for the app run.

> If the user select Apple then token 99 should be returned.
> If Orange, Apple were all the same length then I could get an index from an
> Instr calculation, but they can be most any length.
> Seems there must be something faster than a For  Next loop of items set in
> an array.
> yes, VB6
> suggestions please



Mon, 12 Mar 2012 02:22:01 GMT  
 Fastest Selection

Quote:
> User entry is all up front and may come from a data file..
> I tried these two methods.

Faster methods involve using binary search or hash tables. I believe that
the Collection object uses hash tables.

http://en.wikipedia.org/wiki/Hash_table

Quote: "In many situations, hash tables turn out to be more efficient than
search trees or any other table lookup structure. For this reason, they are
widely used in many kinds of computer software, particularly for associative
arrays, database indexing, caches, and sets."



Mon, 12 Mar 2012 03:24:20 GMT  
 Fastest Selection


Quote:


>> > I need to rapidly get a token from a string list.

>> One idea off the top of my head, use a collection and a class module.

> Why the class?    List.Add 99, "Apple"   Would suffice.

Just so both the name and token would be stored.  If you do what you're
suggesting, there'd be no way to get Apple knowing only that the token is 99
(IOW, the reverse of looking up the token value). VB's collection object
does not expose the key for items in the collection, so you couldn't just
loop through it. If Lorin doesn't need that capability, then what you
suggest is probably fine. Or, he could use a Dictionary object from the
Scripting library (or whatever library has the Dictionary, I think it's
Scripting).

--
Mike



Mon, 12 Mar 2012 03:49:26 GMT  
 Fastest Selection

Quote:
> Faster methods involve using binary search or hash tables. I believe that
> the Collection object uses hash tables.

> http://en.wikipedia.org/wiki/Hash_table

Here is a test result using array looping and collection. Adding to the
array is fast, but adding to the collection is slow, however, when searching
later, a collection is much faster. Here is the test result for 10,000,000
strings on Intel 2.4 GHz CPU and XP+SP2, in the VB IDE(Timer resolution is
15.625 ms in this system):

Time(Loading array): 7.8125
Time(Loading collection): 92.98438
Time(searching whole array): 0.78125
 10000000
Time(searching whole collection): 0

' Form1 code

Option Explicit

Private Sub Form_Load()
    Const MAX_LOOP = 1000000
    Dim i As Long
    Dim s As String
    Dim sArray(MAX_LOOP) As String
    Dim o As Collection
    Dim t As Single

    Set o = New Collection

    t = Timer
    For i = 1 To MAX_LOOP
        sArray(i) = Str(i)
    Next
    Debug.Print "Time(Loading array): " & Timer - t

    t = Timer
    For i = 1 To MAX_LOOP
        o.Add Str(i), Str(i)
    Next
    Debug.Print "Time(Loading collection): " & Timer - t

    s = Str(MAX_LOOP) ' Last added item
    t = Timer
    For i = 1 To MAX_LOOP
        If s = sArray(i) Then
            Exit For
        End If
    Next
    Debug.Print "Time(searching whole array): " & Timer - t

    t = Timer
    Debug.Print o(s)
    Debug.Print "Time(searching whole collection): " & Timer - t

End Sub



Mon, 12 Mar 2012 04:39:15 GMT  
 
 [ 12 post ] 

 Relevant Pages 

1. my game is too fast on faster computers

2. TreevView selection - hierarchical selection

3. Capturing the selection from HTML selection lists

4. read a big file fast, very fast!! HELP!!

5. Reading a file, a big file, fast, very fast!!

6. VB Selection formula does not work if Report contains Selection Formula ?

7. VB Selection formula does not work if Report contains Selection Formula ?

8. recordset, make it faster

9. Fast Way to update one field in one record

10. Which way is faster

11. Which method works faster:DAO or SQL

12. Faster Recordset

 

 
Powered by phpBB® Forum Software