udfArrayItemLocate Performancetest
;------------------------------------------------------------------------------------------------------------------------------------------
; udfArrayItemLocate Performancetest
;
; This performancetest runs four slightly different coded
; binary search algorithms on a WinBatch array.
;
; Detlev Dalitz.20020821.20090507.
;------------------------------------------------------------------------------------------------------------------------------------------

;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfArrayItemLocateV1 (arrArray, anyItem)
If VarType (arrArray) != 256 Then Return -1 ; No array.
If ArrInfo (arrArray, 6) == 0 Then Return -1 ; No elements.
If ArrInfo (arrArray, 0) > 1 Then Return -1 ; Too much dimensions.
intTop = Max (0, ArrInfo (arrArray, 1) - 1)
intBot = 0
While @TRUE
   If intBot == intTop
      If anyItem == arrArray [intBot] Then Return intBot
         Else Return -1
   EndIf
   intMid = (intBot + intTop) / 2
   If anyItem > arrArray [intMid] Then intBot = 1 + intMid
      Else intTop = intMid
EndWhile
;..........................................................................................................................................
; This UDF "udfArrayItemLocate" uses the binary search algorithm
; to locate a given Item in a given ascending sorted array.
; The function returns the index number of the found element,
; otherwise returns -1 if the Item was not found or if the given array does not fit.
;
; The algorithm needs an ascending sorted array.
;
; Detlev Dalitz.20020821.20090507.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfArrayItemLocateV2 (arrArray, anyItem)
If VarType (arrArray) != 256 Then Return -1 ; No array.
If ArrInfo (arrArray, 6) == 0 Then Return -1 ; No elements.
If ArrInfo (arrArray, 0) > 1 Then Return -1 ; Too much dimensions.
intTop = Max (0, ArrInfo (arrArray, 1) - 1)
intBot = 0
intMid = intTop / 2
While @TRUE
   If arrArray [intMid] > anyItem
      intTop = intMid - 1
      intMid = intMid - ((intMid - intBot) / 2)
   Else
      intBot = intMid
      intMid = intMid + ((intTop - intMid) / 2)
   EndIf
   If (intTop - intBot) <= 1 Then Break
EndWhile
If arrArray [intTop] == anyItem Then Return intTop
If arrArray [intBot] == anyItem Then Return intBot
Return -1
;..........................................................................................................................................
; This UDF "udfArrayItemLocate" uses the binary search algorithm
; to locate a given Item in a given ascending sorted array.
; The function returns the index number of the found element,
; otherwise returns -1 if the Item was not found or if the given array does not fit.
;
; The algorithm needs an ascending sorted array.
;
; Detlev Dalitz.20020821.20090507.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------

;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfArrayItemLocateV3 (arrArray, anyItem)
If VarType (arrArray) != 256 Then Return -1 ; No array.
If ArrInfo (arrArray, 6) == 0 Then Return -1 ; No elements.
If ArrInfo (arrArray, 0) > 1 Then Return -1 ; Too much dimensions.
intTop = Max (0, ArrInfo (arrArray, 1) - 1)
intBot = 0
While intTop >= intBot
   intMid = (intBot + intTop) / 2
   If anyItem == arrArray [intMid] Then Return intMid
   If anyItem < arrArray [intMid] Then intTop = intMid - 1
      Else intBot = intMid + 1
EndWhile
Return -1
;..........................................................................................................................................
; This UDF "udfArrayItemLocate" uses the binary search algorithm
; to locate a given Item in a given ascending sorted array.
; The function returns the index number of the found element,
; otherwise returns -1 if the Item was not found or if the given array does not fit.
;
; The algorithm needs an ascending sorted array.
;
; Detlev Dalitz.20020821.20090507.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------

;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfArrayItemLocateV4 (arrArray, anyItem)
If VarType (arrArray) != 256 Then Return -1 ; No array.
If ArrInfo (arrArray, 6) == 0 Then Return -1 ; No elements.
If ArrInfo (arrArray, 0) > 1 Then Return -1 ; Too much dimensions.
intTop = Max (0, ArrInfo (arrArray, 1) - 1)
intBot = 0
While (intTop - intBot - 1)
   intMid = (intTop + intBot) / 2
   If anyItem > arrArray [intMid] Then intBot = intMid
      Else intTop = intMid
EndWhile
If arrArray [intTop] == anyItem Then Return intTop
If arrArray [intBot] == anyItem Then Return intBot
Return -1
;..........................................................................................................................................
; This UDF "udfArrayItemLocate" uses the binary search algorithm
; to locate a given Item in a given ascending sorted array.
; The function returns the index number of the found element,
; otherwise returns -1 if the Item was not found or if the given array does not fit.
;
; The algorithm needs an ascending sorted array.
;
; Detlev Dalitz.20020821.20090507.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


; Test.

:Performancetest
strMsgTitle = "Demo: udfArrayItemLocate (arrArray, anyItem)  Performance Test"

intTestHigh = 4
intTestLow = 1

intLoopHigh = 400
intLoopLow = 1

anyItem1 = "ZZZ"     ; -1 ; Item is not in array, beyond right edge.
anyItem2 = "???"     ; -1 ; Item is not in array, beyond left edge.
anyItem3 = ""        ;  0 ; Item is in array, left edge.
anyItem4 = "zzzz"    ; 20 ; Item is in array, right edge.
anyItem5 = "drei"    ;  2 ; Item is in array, element 8 from the middle to the left.
anyItem6 = "zero"    ; 18 ; Item is in array, element 8 from the middle to the right.
anyItem7 = "four"    ;  6 ; Item is in array, element 4 from the middle to the left.
anyItem8 = "six"     ; 14 ; Item is in array, element 4 from the middle to the right.

intItemHigh = 8
intItemLow = 1

; Array contains 21 elements, sorted ascending.
arrArray = Arrayize (",acht,drei,eight,eins,five,four,fuenf,neun,nine,one,sechs,seven,sieben,six,three,two,vier,zero,zwei,zzzz", ",")


For intTest = intTestLow To intTestHigh
   intTicks%intTest% = 0
   Display (1, strMsgTitle, "Running Test %intTest%, please wait ...")
   For intItem = intItemLow To intItemHigh
      For intLoop = intLoopLow To intLoopHigh
         Exclusive (@ON)
         intTicksStart = GetTickCount ()
         intResult = udfArrayItemLocateV%intTest% (arrArray, anyItem%intItem%)
         intTicksStop = GetTickCount ()
         Exclusive (@OFF)
         intTicks%intTest% = intTicks%intTest% + intTicksStop - intTicksStart
      Next
   Next
Next

intTicksMax = 0
For intTest = intTestLow To intTestHigh
   intTicksMax = Max (intTicksMax, intTicks%intTest%)
Next
For intTest = intTestLow To intTestHigh
   intPct%intTest% = 100 * intTicks%intTest% / intTicksMax
Next
strMsgText = ""
For intTest = intTestLow To intTestHigh
   strMsgText = strMsgText : "Test " : intTest : @TAB : "Ticks = " : @TAB : intTicks%intTest% : @TAB : intPct%intTest% : " %%" : @LF
Next
ClipPut (strMsgText)
Pause (strMsgTitle, strMsgText)

:CANCEL
Exit
;.................................................
;   Test 1   Ticks =    9220   100 %
;   Test 2   Ticks =    8196    88 %
;   Test 3   Ticks =    6982    75 %
;   Test 4   Ticks =    7188    77 % <== The winner.
;..................................................