INTERACT FORUM
Windows => Plug-in Development => Topic started by: KingSparta on August 12, 2002, 05:58:58 am
-
I was hoping you might know an answer to this.
lets say i have a database (comma delimited) and i need to look for something quick. get the data and get out how would you do that?
right now i am using input to read the database when it finds what it needs then jump out.
is there a faster way?
-
Hi Dude,
There are loads of ways you can speed it up but I need some more info before I can answer:
1) How many records in the file?
2) Does the file contents change often?
3) Is each record in the file a fixed length (I presume not)?
Answer these and I'll be able to give you a more definative answer.
You can also contact me on RhinoBanga@hotmail.com via MSN if you want to realtime chat.
-
>> 1) How many records in the file?
16194
>> 2) Does the file contents change often?
No, It Would Never Change Unless More Top 40 Lines Were Added in Excel
>> 3) Is each record in the file a fixed length (I presume not)?
Nope
I was thinking this morning to make this faster, i could get this info in A MSFlexGrid, read it once, and then Search It somehow (not sure how one would do that, since i never messed with this before).
A Sample Of The Info In the Database (Songname, Artist, Year, ChartPos)
Zorba the Greek, Herb Alpert & The Tijuana Brass, 1966, 11
-
Since you are using VB I'd:
1) Load the data into a listview ... each subitem is a field.
2) When you want to do a search sort by the subitem in question and perform a binary chop search of the listview records.
That will guarentee that it will only take up to a maximum of 14 reads to find the entry you are after.
If you don't know about binary chopping let me know and I'll explain it to you.
-
>> 2) When you want to do a search sort by the subitem in question
>> and perform a binary chop search of the listview records.
Easy For You To Say
>> perform a binary chop search
Not A Clue
I Did Pull Up A ListView Just to check it out
I did not find anything in the help about "Binary Chop Search" however
-
Been doing some reading about list view
there is a search option
FindItem string, value, index, match
Value, index, match are all optional.
a sample is
Set LItem = ListView1.FindItem(FindItem, LvwText, , Lvwpartial)
i guess that would find something, then i guess i could somehow use that and somehow tell it to get the data from the 4 boxes in the listview.
I guess?
-
Don't worry dude ... binary chopping is a concept.
It means with a sorted list you can take the number of records and find the middle record. If the value you are looking for is less than the one at this position then you can discard the data beyon that record. If it's greater then you can discard anything below it. You repeat this until you find you data.
For example say you had 5 records containing two fields like so:
DEF 456
ABC 123
JKL 012
GHI 789
MNO 345
Now if you wanted to find GHI, traditionally you would do a sequential (or linear) search and you would find it at after 4 reads.
If you sorted the data first, e.g.:
ABC 123
DEF 456
GHI 789
JKL 012
MNO 345
And then performed a "Binary Chop" of the data you would find it in ONE read, e.g.:
1) Find the middle point ... which is record 3
2) Compare to the search criteria ... it matches so you are done.
Say you wanted to find MNO:
1) Find the middle point ... which is record 3
2) Compare to the search criteria ... it's greater than so can discard records 1, 2 and 3.
3) Find the middle point in the remaining records ... since there's only two you take the lower entry
3) Compare to the search criteria ... it's greater than so can discard records 4.
4) Since you now only have one left you can compare ... and it matches.
So with the unsorted data it would have taken 5 reads ... with binary chopping it takes 3.
Just apply this concept with the listview. Add the records, sort by the field you want, then manually perform the binary chop looking for your data.
-
I think the problem with the FindItem method is that it's still a linear search.
-
I see what your saying now...
I will do some more research and build a demo to see if i can get something working
You Would Not Have A Sample To Look At Would You?
:-)
I Asked You Since You Tend To Be Smarter Than Me.
-
I don't have a sample dude but if you get stuck email me your demo and I'll look at it for you.
P.S. It's nothing to do with being smarter ... it's just I've been programming for nearly 20 years now ... so I've been around the block so to speak :D
-
hehehe
I hear you...
Thanks For Pointing Me In The Right Direction.
Later
PS: Something I Found
Public Type demBC
keyValue as String * 10
targetValue as String * 50
End Type
Public BCArray() as demBC
Public Function BinaryChop(SearchValue as String) as Long
Dim StopPoint As Long, LowPoint As Long, HighPoint As Long
Dim ChopCount As Long, ChopPoint As Long
Dim ElemCnt as Long
Dim Check1 As String, Check2 As String
Const ValueNotFound = -32767
ArrayStart = LBound(BCArray())
ArrayEnd = UBound(BCARRAY())
If LBound(BCArray()) < 0 then
ElemCnt = Abs(LBound(BCArray())) |PLS| Abs(UBound(BCArray())) |PLS| 1
Else
ElemCnt = UBound(BCArray()) - LBound(BCArray()) |PLS| 1
End If
StopPoint = 1
Do Until 2 ^ StopPoint >= ElemCnt ‘work out the maximum number of elements
StopPoint = StopPoint |PLS| 1 ‘that need to be read to find the value
Loop
StopPoint = StopPoint |PLS| 1
LowPoint = LBound(BCArray())
HighPoint = UBound(BCArray())
ChopPoint = ((HighPoint - LowPoint) / 2) |PLS| LowPoint
Check1 = Right$(String$(10, “0”) & UCase$(SearchValue), 10)
‘We may have to deal with the problem of variable character counts so it can be a
‘good idea to pad the strings with leading characters of a low ASCII value
‘Plus this search is case insensitive - hence the UCase$() function
‘If you need case sensitivity - take it out
Check2 = Trim$(BCArray(ChopPoint).keyvalue)
Check2 = Right$(String$(10, “0”) & Ucase$(Check2), 10)
Do Until Check1 = Check2 Or ChopCount >= StopPoint
If Check2 < Check1 Then
LowPoint = ChopPoint
Else
HighPoint = ChopPoint
End If
ChopCount = ChopCount |PLS| 1
ChopPoint = (HighPoint - LowPoint) / 2 |PLS| LowPoint
Check2 = Trim$(BCArray(ChopPoint).keyvalue)
Check2 = Right$(String$(10, “0”) & Ucase$(Check2), 10)
Loop
If Check1 = Check2 then
BinaryChop = ChopPoint
Else
BinaryChop = ValueNotFound
End If
End Function
-
Excellent ... now you just have to adapt it to reading a LVW.
-
Thats What I Was Thinking....
In the Mean Time I Created A Program Using The Listview, Filled The DataGrid, And Using The Finditem Command You Can Search And Once It Finds It, Selects Item, And I Can Have It Fill Four Text Boxes (SongName, Artist Name, Year, And Chart Position) With What Was Found.
So It Is Possable To Use It (Maybe)
Not Sure What One Would Be Faster, Maybe I Can Figure That Out Later.
At Any Rate I Will Play With Both
Like I Said, Thanks For The Help
UPDATE:
I Think I Will Be Using The FindItem Command, It Will Search To The End Of A 20000 Line Database In Less Than A 1\2 Second (I Could Not Start The Stop Watch And It Was Done).
-
Be carefull though dude ... it may take 1/2 a second on your computer ... what about those with slower ones?
At least with sorting/binary chop you can guarantee a sub-second response time.