Profiling recursive file counting
;==========================================================================================================================================
; Recursive counting of files.
;
; Profiling Performance Test.
;
;   - WinBatch Extender "File and Folder Finder"
;
;   - WinBatch User Defined Function
;
;   - LogParser.exe
;
;------------------------------------------------------------------------------------------------------------------------------------------
; (c)Detlev Dalitz.20100228.20100301.
;==========================================================================================================================================

;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfFileCount (strfolderStart, strFileType, intflags)
AddExtender ("wwfaf44i.dll")
intFC = 0
hdlFAF = fafOpen (strfolderStart, strFileType, intFlags)
While @TRUE
   If fafFind (hdlFAF) == "" Then Break
   intFC = intFC + 1
EndWhile
fafClose (hdlFAF)
Return intFC
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfFileCountRecursive (strFileSpec)
strFP = FilePath (strFileSpec)
strFB = FileBaseName (strFileSpec)
strFL = FileItemPath (strFileSpec)
intFC = ItemCount (strFL, @TAB)
strDL = DirItemize (strFP : "\*")
intDC = ItemCount (strDL, @TAB)
For intI = 1 To intDC
   intFC = intFC + udfFileCountRecursive (strFP : ItemExtract (intI, strDL, @TAB) : "\" : strFB)
Next
Return intFC
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfFileCountLP (strfolderStart, strFileType)
strFileTemp = FileCreateTemp ("")
objLogParser = ObjectCreate ("MSUtil.LogQuery")
objInputFormat = ObjectCreate ("MSUtil.LogQuery.FileSystemInputFormat")
objInputFormat.recurse = -1
objOutputFormat = ObjectCreate ("MSUtil.LogQuery.NativeOutputFormat")
objOutputFormat.headers = @FALSE
strQuery = "SELECT COUNT (*) INTO '" : strFileTemp : "' 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
intFC = ItemExtract (1, FileGet (strFileTemp), @CR)
FileDelete (strFileTemp)
Return intFC
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


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

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


;blnFinalResultOnly = @TRUE
blnFinalResultOnly = @FALSE


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

strFileSpec = strfolderStart : strFileType

Exclusive (@ON)
intTickStart = GetTickCount ()

intIC5Prev = IntControl (5, 1, 0, 0, 0) ; System & Hidden files or directories are seen and used.
intCount1 = udfFileCountRecursive (strFileSpec)
IntControl (5, intIC5Prev, 0, 0, 0)

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

If !blnFinalResultOnly Then Message ("Result", "Filespec = " : strFilespec : @LF : "Count = " : intCount1)
;------------------------------------------------------------------------------------------------------------------------------------------


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

intFlags = 19 ; 19 = 1|2|16 = Hidden|System|Subfolders.

Exclusive (@ON)
intTickStart = GetTickCount ()

intCount2 = udfFileCount (strfolderStart, strFileType, intFlags)

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

If !blnFinalResultOnly Then Message ("Result", "Filespec = " : strFilespec : @LF : "Count = " : intCount2)
;------------------------------------------------------------------------------------------------------------------------------------------


;---;
; 3 ;
;---+--------------------------------------------------------------------------------------------------------------------------------------
; Test LogParser.
;------------------------------------------------------------------------------------------------------------------------------------------
:Test3
strName3 = "LP"

strFileSpec = strfolderStart : strFileType

Exclusive (@ON)
intTickStart = GetTickCount ()

intCount3 = udfFileCountLP (strfolderStart, strFileType)

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

If !blnFinalResultOnly Then Message ("Result", "Filespec = " : strFilespec : @LF : "Count = " : intCount3)
;------------------------------------------------------------------------------------------------------------------------------------------


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

intTestMin = 1
intTestMax = 3
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   7750  77.6    230  UDF
;    2   1094  11.0    230  FaF
;    3   1141  11.4    230  LP
;------------------------------------------------------------------------------------------------------------------------------------------
; Test  Ticks   Pct  Count  Name
;    1   7610  72.9   2825  UDF
;    2   1672  16.0   2825  FaF
;    3   1156  11.1   2825  LP
;------------------------------------------------------------------------------------------------------------------------------------------
; Test  Ticks   Pct  Count  Name
;    1   8172  60.6  11314  UDF
;    2   3875  28.7  11314  FaF
;    3   1437  10.7  11314  LP
;------------------------------------------------------------------------------------------------------------------------------------------