Profiling recursive file searching
;==========================================================================================================================================
; Recursive searching for files and building a string list.
;
; Profiling Performance Test.
;
;   - WinBatch Extender "File and Folder Finder"
;
;   - WinBatch User Defined Function
;
;   - CMD.EXE's DIR command
;
;   - LogParser.exe
;
;------------------------------------------------------------------------------------------------------------------------------------------
; (c)Detlev Dalitz.20100226.20100227.20100301.
;==========================================================================================================================================


strfolderStart = ShortCutDir (36, 0, 1) ; Windows directory.

strFileType = "*.jpg"
;strFileType = "*.exe"
;strFileType = "*.dll"

;blnFinalResultOnly = @TRUE
blnFinalResultOnly = @FALSE


;---;
; 1 ;
;---+--------------------------------------------------------------------------------------------------------------------------------------
; Test FaF.
;------------------------------------------------------------------------------------------------------------------------------------------
:Test1
strName1 = "FaF"

AddExtender ("wwfaf44i.dll")

Exclusive (@ON)
intTickStart = GetTickCount ()

strList = ""
hdlFAF = fafOpen (strfolderStart, strFileType, 19) ; 19 = 1|2|16 = Hidden|System|Subfolders.
While @TRUE
   strResult = @TAB : fafFind (hdlFAF)
   If strResult == @TAB Then Break
   strList = strList : strResult
EndWhile
fafClose (hdlFAF)
strList = StrSub (strList, 2, -1)

intTicks1 = GetTickCount () - intTickStart
Exclusive (@OFF)

intCount1 = ItemCount (strList, @TAB)

strList = ItemSort (strList, @TAB)
If !blnFinalResultOnly Then AskItemlist ("Test 1|Count=" : intCount1 : "|Ticks=" : IntTicks1, strList, @TAB, @UNSORTED, @SINGLE)

;FilePut (FileCreateTemp ("L1_"), StrReplace (strList, @TAB, @CRLF))
;------------------------------------------------------------------------------------------------------------------------------------------



;---;
; 2 ;
;---+--------------------------------------------------------------------------------------------------------------------------------------
; Test UDF.
;------------------------------------------------------------------------------------------------------------------------------------------
:Test2
strName2 = "UDF"

;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfFileItemPathRecursive (strFileSpec)
strFP = FilePath (strFileSpec)
strFB = FileBaseName (strFileSpec)
strFL = FileItemPath (strFileSpec)
strDL = DirItemize (strFP : "\*")
intDC = ItemCount (strDL, @TAB)
For intI = 1 To intDC
   strTmp = udfFileItemPathRecursive (strFP : ItemExtract (intI, strDL, @TAB) : "\" : strFB)
   If strTmp != "" Then strFL = ItemInsert (strTmp, -1, strFL, @TAB)
Next
Return strFL
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------

Exclusive (@ON)
intTickStart = GetTickCount ()

intIC5Prev = IntControl (5, 1, 0, 0, 0) ; System & Hidden files or directories are seen and used.
strList = udfFileItemPathRecursive (strfolderStart : strFileType)
IntControl (5, intIC5Prev, 0, 0, 0)

intTicks2 = GetTickCount () - intTickStart
Exclusive (@OFF)

intCount2 = ItemCount (strList, @TAB)

strList = ItemSort (strList, @TAB)
If !blnFinalResultOnly Then AskItemlist ("Test 2|Count=" : intCount2 : "|Ticks=" : IntTicks2, strList, @TAB, @UNSORTED, @SINGLE)

;FilePut (FileCreateTemp ("L2_"), StrReplace (strList, @TAB, @CRLF))
;------------------------------------------------------------------------------------------------------------------------------------------



;---;
; 3 ;
;---+--------------------------------------------------------------------------------------------------------------------------------------
; Test DIR command.
;------------------------------------------------------------------------------------------------------------------------------------------
:Test3
strName3 = "DIR"

Exclusive (@ON)
intTickStart = GetTickCount ()

strFileList = FileCreateTemp ("")
intResult = RunHideWait (Environment ("ComSpec"), '/U /C DIR /-P /A:-D /B /S "' : strfolderStart : strFileType : '">"' : strFileList : '"')
strList = StrTrim (StrReplace (FileGet (strFileList), @CRLF, @TAB))
blnResult = FileDelete (strFileList)

intTicks3 = GetTickCount () - intTickStart
Exclusive (@OFF)

intCount3 = ItemCount (strList, @TAB)

strList = ItemSort (strList, @TAB)
If !blnFinalResultOnly Then AskItemlist ("Test 3|Count=" : intCount3 : "|Ticks=" : IntTicks3, strList, @TAB, @UNSORTED, @SINGLE)

;FilePut (FileCreateTemp ("L3_"), StrReplace (strList, @TAB, @CRLF))
;------------------------------------------------------------------------------------------------------------------------------------------
; Note: There is a shortage with the DIR command in combination with wildcarded search.
;       DIR "*.abc" will find "x.abc" and "x.abcd" too.
;       DIR gives more hits than actually needed.
;       Therefore the scope of the DIR command is limited.
;------------------------------------------------------------------------------------------------------------------------------------------



;---;
; 4 ;
;---+--------------------------------------------------------------------------------------------------------------------------------------
; Test LP.
;------------------------------------------------------------------------------------------------------------------------------------------
:Test4
strName4 = "LP"

Exclusive (@ON)
intTickStart = GetTickCount ()

strFileList = FileCreateTemp ("")

objLogParser = ObjectCreate ("MSUtil.LogQuery")
objInputFormat = ObjectCreate ("MSUtil.LogQuery.FileSystemInputFormat")
objInputFormat.recurse = -1
objOutputFormat = ObjectCreate ("MSUtil.LogQuery.NativeOutputFormat")
objOutputFormat.headers = @FALSE
;strQuery = "SELECT Path INTO '":strFileList:"' from '":strfolderStart : strFileType ; Note: This line works like CMD.EXE's DIR command, see added Note in Test 3.
strQuery = "SELECT Path INTO '" : strFileList : "' from '" : strfolderStart : strFileType : "'" : " WHERE (INDEX_OF(Attributes,'D')<>0) AND (TO_UPPERCASE(EXTRACT_SUFFIX(PATH,0,'.'))='" : StrUpper (FileExtension (strFileType)) : "')"
objLogParser.ExecuteBatch(strQuery, objInputFormat, objOutputFormat)
objOutputFormat = 0
objInputFormat = 0
objLogParser = 0

strList = StrTrim (StrReplace (FileGet (strFileList), @CRLF, @TAB))
blnResult = FileDelete (strFileList)

intTicks4 = GetTickCount () - intTickStart
Exclusive (@OFF)

intCount4 = ItemCount (strList, @TAB)

strList = ItemSort (strList, @TAB)
If !blnFinalResultOnly Then AskItemlist ("Test 4|Count=" : intCount4 : "|Ticks=" : IntTicks4, strList, @TAB, @UNSORTED, @SINGLE)

;FilePut (FileCreateTemp ("L4_"), StrReplace (strList, @TAB, @CRLF))
;------------------------------------------------------------------------------------------------------------------------------------------



;------------------------------------------------------------------------------------------------------------------------------------------
; Result.
;------------------------------------------------------------------------------------------------------------------------------------------

intTestMin = 1
intTestMax = 4
Decimals (1)
intTicksSum = 0
For intTest = intTestMin To intTestMax
   intTicksSum = intTicksSum + intTicks%intTest%
Next
If intTicksSum < 1 Then intTicksSum = 1 ; To prevent dividing by zero.
For intTest = intTestMin To intTestMax
   intPct%intTest% = 100.0 * intTicks%intTest% / intTicksSum
Next

; Format output.
strTest = "Test"
strTicks = "Ticks"
strPct = "Pct"
strCount = "Count"
strName = "Name"
strSep = "  "
strPre = "; "
intLenTest = Max (StrLen (strTest), StrLen (intTestMax))
intLenTicks = StrLen (strTicks)
intLenPct = StrLen (strPct)
intLenCount = StrLen (strCount)
intLenFunction = StrLen (strName)
For intTest = intTestMin To intTestMax
   intLenTicks = Max (intLenTicks, StrLen (intTicks%intTest%))
   intLenPct = Max (intLenPct, StrLen (intPct%intTest%))
   intLenCount = Max (intLenCount, StrLen (intCount%intTest%))
   intLenFunction = Max (intLenFunction, StrLen (strName%intTest%))
Next
strTest = StrFixLeft (strTest, " ", intLenTest)
strTicks = StrFixLeft (strTicks, " ", intLenTicks)
strPct = StrFixLeft (strPct, " ", intLenPct)
strResult = ""
;strResult = ItemInsert (strPre : "Iterations: " : intLoopMax, -1, strResult, @LF)
strResult = ItemInsert (strPre : strTest : strSep : strTicks : strSep : strPct : strSep : strCount : strSep : strName, -1, strResult, @LF)
For intTest = intTestMin To intTestMax
   strTest = StrFixLeft (intTest, " ", intLenTest)
   strTicks = StrFixLeft (intTicks%intTest%, " ", intLenTicks)
   strPct = StrFixLeft (intPct%intTest%, " ", intLenPct)
   strCount = StrFixLeft (intCount%intTest%, " ", intLenCount)
   strName = StrFix (strName%intTest%, " ", intLenFunction)
   strResult = ItemInsert (strPre : strTest : strSep : strTicks : strSep : strPct : strSep : strCount : strSep : strName, -1, strResult, @LF)
Next
strResult = strResult : @LF
Message ("Performance Test Result", strResult)
ClipPut (strResult)

:CANCEL
Exit
;------------------------------------------------------------------------------------------------------------------------------------------
; Test  Ticks   Pct  Count  Name
;    1   1203  10.8    230  FaF
;    2   7719  69.2    230  UDF
;    3   1125  10.1    230  DIR
;    4   1110   9.9    230  LP
;------------------------------------------------------------------------------------------------------------------------------------------
; Test  Ticks   Pct  Count  Name
;    1   6750  35.6   2825  FaF
;    2   9719  51.2   2825  UDF
;    3   1266   6.7   2841  DIR
;    4   1250   6.6   2825  LP
;------------------------------------------------------------------------------------------------------------------------------------------
; Test  Ticks   Pct  Count  Name
;    1  84172  84.8  11314  FaF        Small speed up by changing concatenation code. DD.20100227.
;    2  11719  11.8  11314  UDF
;    3   1859   1.9  11408  DIR
;    4   1500   1.5  11314  LP
;==========================================================================================================================================