> You'd be amazed at how many times the question of RB's speed comes up in
> these lists, and how often it turns out that there is a way to write the
> code so that will not only be as fast as the rivals, it will often be
> faster.
I've only been using RB for about 9 months, and am definitely still learning
things every day, thanks mostly to the kind folks on these lists.
Here's a bit of code from the middle of my sort, which may give you an idea
why I've been having trouble finding ways to use use RB's built-in sort
methods and why this particular sort is so messy.
The data is originates as text that contains numbers (such as "100", "100b",
"100.42", "N43", "A24" and "AG16"), and there are very specific rules about
what kinds of suffixes and prefixes go where in the sort order. I convert
the data to integers for storage and sorting purposes. There are also times
when the user has assigned a specific rank to those entries irrespective of
their number values. Anyway, here's a code snippet that compares two of
these numbers:
(FA and FC point to where the actual data is stored, DoMore=True tells the
sort to proceed to the next level of comparisons)
Case kAsUnitNumber
If FA < 0 Or FC < 0 Then GoTo UnitEnd 'Skip over negative numbers
If WhichShow.GetVal(FA, kRankH) = WhichShow.GetVal(FC, kRankH) Then
GoTo UnitSort
If WhichShow.GetVal(FA, kRankH) > WhichShow.GetVal(FC, kRankH) Then
SwapThem = True
GoTo UnitEnd
UnitSort:
'We only enter here if ranks are equal
AD = WhichShow.GetVal(FA, DataCat)
CD = WhichShow.GetVal(FC, DataCat)
If AD = CD Then'Unit numbers are identical
'So look at their attributes:
ASlot = FNAttSlot(WhichShow.GetVal(FA, kAttBitsH))
CSlot = FNAttSlot(WhichShow.GetVal(FC, kAttBitsH))
AAtt = FNAttNum(WhichShow.GetVal(FA, kAttBitsH))
CAtt = FNAttNum(WhichShow.GetVal(FC, kAttBitsH))
If ASlot = CSlot And AAtt = CAtt Then
DoMore = True
GoTo UnitEnd
End If
If ASlot <> CSlot Then
DoMore = True
GoTo UnitEnd
End If
If ASlot = CSlot Then
If AAtt > CAtt Then
SwapThem = True
End If
End If
GoTo UnitEnd
End If
If AD = 0 And CD <> 0 Then
GoTo UnitEnd
End If
If AD <> 0 And CD = 0 Then
SwapThem = True
GoTo UnitEnd
End If
RootA = FNUnitRoot(AD)
RootC = FNUnitRoot(CD)
OtherA = FNUnitFlags(AD)
OtherC = FNUnitFlags(CD)
'Flags:
'0=No prefix or suffix
'1=Decimal suffix
'2=Letter Suffix
'3=Letter Prefix
If OtherA = 0 And OtherC = 0 Then
If RootA < RootC Then
GoTo UnitEnd
End If
If RootA > RootC Then
SwapThem = True
'Then they must be out of order
GoTo UnitEnd
End If
If RootA = RootC Then
DoMore = True
GoTo UnitEnd
End If
End If
If OtherA <> 3 And OtherC <> 3 Then'The root number is what matters
most
If RootA < RootC Then
GoTo UnitEnd
End If
If RootA > RootC Then
SwapThem = True
'Then they must be out of order
GoTo UnitEnd
End If
'By here, RootA must equal RootC
If OtherA < OtherC Then 'No matter the suffixes, sort by kind of
number
GoTo UnitEnd
End If
If OtherA > OtherC Then
SwapThem = True
GoTo UnitEnd
End If
'By here, Roots are equal and Others are equal
Select Case OtherA 'Could just as well be OtherC
Case 0
'Nothing to do
GoTo UnitEnd
Case 1 'Decimal suffix
DecimalA = FNUnitDecimal(AD)
DecimalC = FNUnitDecimal(CD)
If DecimalA = DecimalC Then
DoMore = True
GoTo UnitEnd
End If
If DecimalA > DecimalC Then
SwapThem = True
GoTo UnitEnd
End If
If DecimalA < DecimalC Then
GoTo UnitEnd
End If
Case 2 'Letter Suffixes
PrefixA = FNUnitFirst(AD)
SuffixA = FNUnitSecond(AD)
PrefixC = FNUnitFirst(CD)
SuffixC = FNUnitSecond(CD)
Astr = Chr(64 + PrefixA) + Chr(64 + SuffixA)
BStr = Chr(64 + PrefixC) + Chr(64 + SuffixC)
If Astr > BStr Then
SwapThem = True
GoTo UnitEnd
End If
If Astr < BStr Then
GoTo UnitEnd
End If
If Astr = BStr Then
DoMore = True
GoTo UnitEnd
End If
Case 3 'We'll never get here, at least theoretically
End Select
Else
If OtherA = 3 And OtherC <> 3 Then 'Prefixes sort AFTER suffixes
SwapThem = True
GoTo UnitEnd
End If
If OtherC = 3 And OtherA <> 3 Then 'Prefixes sort AFTER suffixes
GoTo UnitEnd
End If
'Unit numbers that start with letters:
PrefixA = FNUnitFirst(AD)
PrefixC = FNUnitFirst(CD)
SuffixA = FNUnitSecond(AD)
SuffixC = FNUnitSecond(CD)
If SuffixA = 0 And SuffixC <> 0 Then
GoTo UnitEnd
End If
If SuffixA <> 0 And SuffixC = 0 Then
SwapThem = True
GoTo UnitEnd
End If
Astr = Chr(PrefixA + 64) + Chr(SuffixA + 64)
BStr = Chr(PrefixC + 64) + Chr(SuffixC + 64)
If Astr > BStr Then
SwapThem = True
GoTo UnitEnd
End If
If Astr < BStr Then
GoTo UnitEnd
End If
'letters match, check the numbers:
'So test the root numbers:
If RootA < RootC Then
GoTo UnitEnd
End If
If RootA > RootC Then
SwapThem = True
GoTo UnitEnd
End If
If RootA = RootC Then
DoMore = True
GoTo UnitEnd
End If
End If
UnitEnd:
I spent yesterday putting together a linked list structure for the data,
which keeps things sorted all the time while permitting relatively easy
insertion and removal of items. So far, it's improved the speed
tremendously, the next step is improving the speed of the indexing. Still,
there are occasions where it'll be faster to simply sort the data when it's
only temporary data used once, hence this sort, heaven help me...;)
Thanks!
- John
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>
Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>