Moderators SmOke_N Posted July 1, 2009 Moderators Share Posted July 1, 2009 Hi Danny35, you'll run into a recursion issue on very (very very) large directories (4810 I believe). Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
Spiff59 Posted July 2, 2009 Share Posted July 2, 2009 (edited) I only added the "For $y = 1 to 10/next" loop to give more of an average time of function calls, compensate for disk caching, etc. The NT version still holds up pretty well against the Ex. But there have been tons of BugTrac requests over time, and tons of threads regarding enhancing _FileListToArray either functionally, or performance-wise. There's a thread or two right now running concurrent to this one that are on the same topic. I think that indicates that A: Everyone thinks that FIleListToArray needs a makeover, and B: Most everyone has their own idea how to go about it. Alternative methods, ideas, suggestions are all great for producing the best product possible. One that might cut the number of BugTrac enhancement requests, and forum discussions down to a minimum for a long time to come. I almost wonder if once we think we've reached the best result we can, one that is polished and tested, that we ought to open up one last (new) forum thread titled something like "Open Discussion: New _FileListToArray() proposal" then subtitle it "Beat it, break it, or make it better!". The purpose would be to suck in those participating in other similar threads to get them involved and ensure there is not something better floating around out there. I'm rambling... pardon. CODEexpandcollapse popup#include <File.au3> #include <Date.au3> #include <Array.au3> $Path = "C:\Program Files\Autoit3" For $x = 0 To 2 CalcTime('Start') For $y = 1 to 10 $aFiles = _FileListToArrayNT($Path, '*', $x, 2, 1, '', 0) Next $error = @error $Time1 = Int(CalcTime('Finish')) If IsArray($aFiles) Then ConsoleWrite('Files/Folders ' & UBound($aFiles) & ' Improve Flag = ' & $x & ' Time: ' & $Time1 & @CRLF) ;_ArrayDisplay($aFiles, 'Improve Flag = ' & $x & ' Time: ' & $Time1) _ArraySort($aFiles, 0) Else ConsoleWrite('Improve Error: ' & $error & ' Flag = ' & $x & ' Time: ' & $Time1 & ' ' & @CRLF) EndIf CalcTime('Start') ;($sPath, $sFilter = '*', $iFlag = 0, $iPathType = 1, $iRecursive = 0, $sExclude = "", $iRetFormat = 0) For $y = 1 to 10 $aFiles = _FileListToArrayEx($Path, '*', $x, 1, 1, '', 2) Next $error = @error $Time2 = Int(CalcTime('Finish')) If IsArray($aFiles) Then ConsoleWrite('Files/Folders ' & UBound($aFiles) & ' Danny35D Flag = ' & $x & ' Time: ' & $Time2 & @CRLF) ;_ArrayDisplay($aFiles, 'Danny35D Flag = ' & $x & ' Time: ' & $Time2) _ArraySort($aFiles) Else ConsoleWrite('Dan Error: ' & $error & ' Flag = ' & $x & ' Time: ' & $Time2 & @CRLF) EndIf If $Time1 < $Time2 Then $Percent = Round(100 - ($Time1/$Time2) * 100, 2) ConsoleWrite('Faster: Improve ' & $Percent & '%' & @CRLF & @CRLF) Else $Percent = Round(100 - ($Time2/$Time1) * 100, 2) ConsoleWrite('Faster Danny35d ' & $Percent & '%' & @CRLF & @CRLF) EndIf Next Func CalcTime($Action, $iMsgBox = 0) Local $CalcTimestamp_2[2], $Msecs, $Secs, $Mins, $Hour If $Action = "Start" Then Global $CalcTimestamp_1[2] $CalcTimestamp_1[0] = TimerInit() ElseIf $Action = "Finish" Then $CalcTimestamp_2[1] = TimerDiff($CalcTimestamp_1[0]) EndIf Return ($CalcTimestamp_2[1]) EndFunc;==>CalcTime ;=============================================================================== Func _FileListToArrayEx($sPath, $sFilter = '*', $iFlag = 0, $iPathType = 1, $iRecursive = 0, $sExclude = "", $iRetFormat = 0, $iRunFirstTime = 1) Local $aFileList = '', $aFolderList = '', $Tmp = '', $sMask If $iRunFirstTime Then $sPath = StringRegExpReplace($sPath, '\\+$', ''); Removed trailing backslash If Not FileExists($sPath) Then Return SetError(1, 1, 'Path Not Found Or Invalid.') If StringRegExp($sFilter, '[\\/:><\|]') Then Return SetError(2, 2, 'Invalid Mask('& $sFilter & ').') If Not StringRegExp($iFlag, '[012]') Then Return SetError(3, 3, 'Invalid Flag, Chooce (0,1 or 2).') If Not StringRegExp($iPathType, '[01]') Then Return SetError(5, 5, 'Invalid Path Type, Choose (0 or 1).') If Not StringRegExp($iRecursive, '[01]') Then Return SetError(6, 6, 'Invalid Recursive, Choose (0 or 1).') If Not StringRegExp($iRetFormat, '[012]') Then Return SetError(7, 7, 'Invalid RetFormat, Choose (0, 1 or 2).') EndIf $sMask = '(?i)^' & StringReplace(StringReplace(StringReplace($sFilter, '.', '\.'), '*', '.*'), '?', '.') If $sExclude <> '' And $iRunFirstTime Then;convert $sExclude to fit StringRegExp (not perfect but useable) $sExclude = StringStripWS(StringRegExpReplace($sExclude, "\s*;\s*", ";"), 3);Strip leading and trailing spaces and spaces between semi colon delimiter $sExclude = StringRegExpReplace($sExclude, '([\Q\.+[^]$(){}=!\E])', '\\$1');thanks KaFu and Ascend4nt $sExclude = "(?i)\A" & StringReplace(StringReplace(StringReplace($sExclude, "?", "."), "*", ".*?"), ";", "|") & "\z" EndIf $iFirstFile = FileFindFirstFile($sPath & '\*') If @error Then Return While True $iNextFile = FileFindNextFile($iFirstFile) If @error Then ExitLoop $extended = @extended $sFullPath = $sPath & '\' & $iNextFile If $extended = 1 Then If $iFlag <> 1 And ($sFilter = '*' Or $sFilter = '*.*') Then $aFileList &= $sFullPath & '|' If $iRecursive Then If $sExclude <> '' And StringRegExp(StringRegExpReplace($sFullPath, "(.*?[\\/]+)*(.*?\z)", "\2"), $sExclude) Then ContinueLoop $Tmp = _FileListToArrayEx($sFullPath, $sFilter, $iFlag, $iPathType, $iRecursive, $sExclude, 1, 0) If $Tmp <> Chr(38) And $Tmp <> ChrW(38) Then $aFileList &= $Tmp EndIf Else If Not StringRegExp($iNextFile, $sMask) Then ContinueLoop If Not StringRegExp(StringRegExpReplace($sFilter, '^.*\.', ''), '[?*]') Then If StringRegExpReplace($sFilter, '^.*\.', '') <> StringRegExpReplace($iNextFile, '^.*\.', '') Then ContinueLoop EndIf If $sExclude <> '' And StringRegExp(StringRegExpReplace($sFullPath, "(.*?[\\/]+)*(.*?\z)", "\2"), $sExclude) Then ContinueLoop If $iFlag <> 2 Then $aFileList &= $sFullPath & '|' EndIf WEnd FileClose($iFirstFile) If $iRunFirstTime Then $aFileList = StringTrimRight($aFileList, 1) If StringLen($aFileList) = 0 Then Return SetError(4, 4, 'No File(s) Found.') If $iPathType = 0 Then $aFileList = StringReplace($aFileList, $sPath & '', '') If $iRetFormat <> 1 Then $aFileList = StringSplit($aFileList, '|', $iRetFormat) EndIf Return ($aFileList) EndFunc;==>_FileListToArrayEx ;=============================================================================== Func _FileListToArrayNT($sPath = @ScriptDir, $sFilter = "*", $iSearchType = 0, $iPathType = 0, $bRecursiv = False, $sExclude = "", $iRetFormat = 1, $sWorkPath = "") Local $hSearch, $iPCount, $iFCount, $sFile, $sFileList, $sTExclude, $sTWorkPath If $sPath = -1 Or $sPath = Default Then $sPath = @ScriptDir If $sFilter = -1 Or $sFilter = Default Then $sFilter = "*" If $iSearchType = -1 Or $iSearchType = Default Then $iSearchType = 0 If $iPathType = -1 Or $iPathType = Default Then $iPathType = 0 If $bRecursiv = Default Then $bRecursiv = False If $sExclude = -1 Or $sExclude = Default Then $sExclude = "" If $iRetFormat = -1 Or $iRetFormat = Default Then $iRetFormat = 1 Local $aPath = StringSplit($sPath, ';');paths array Local $aFilter = StringSplit($sFilter, ';');filters array If $sExclude Then ;prepare $sTExclude ;strip leading and trailing spaces and spaces between semi colon delimiter $sTExclude = StringStripWS(StringRegExpReplace($sExclude, "\s*;\s*", ";"), 3) ;convert $sExclude to fit StringRegExp (not perfect but useable) $sTExclude = StringRegExpReplace($sTExclude, '([\Q\.+[^]$(){}=!\E])', '\\$1');thanks KaFu and Ascend4nt $sTExclude = StringReplace($sTExclude, "?", ".") $sTExclude = StringReplace($sTExclude, "*", ".*?") $sTExclude = "(?i)\A" & StringReplace($sTExclude, ";", "|") & "\z" For $iPCount = 1 To $aPath[0];Path loop Local $sPathItem = StringStripWS($aPath[$iPCount], 3);strip leading and trailing spaces Local $sDelim = "|";reset $sDelim If StringRight($sPathItem, 1) <> "\" Then $sPathItem &= "\";ensure trailing slash If $iPathType = 2 Then $sDelim &= $sPathItem;return full-path For $iFCount = 1 To $aFilter[0];Filter loop Local $FilterItem = StringStripWS($aFilter[$iFCount], 3);strip leading and trailing spaces If StringRegExp($FilterItem, "[\\/:<>|]") Then ContinueLoop;bypass filters with invalid chars $hSearch = FileFindFirstFile($sPathItem & $FilterItem) If @error Then ContinueLoop Switch $iSearchType Case 1;files Only While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended Then ContinueLoop;bypass folder ;check for exclude files If StringRegExp(StringRegExpReplace($sFile, "(.*?[\\/]+)*(.*?\z)", "\2"), $sTExclude) Then ContinueLoop $sFileList &= $sDelim & $sWorkPath & $sFile WEnd Case 2;folders Only While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended = 0 Then ContinueLoop;bypass file ;check for exclude folder If StringRegExp(StringRegExpReplace($sFile, "(.*?[\\/]+)*(.*?\z)", "\2"), $sTExclude) Then ContinueLoop $sFileList &= $sDelim & $sWorkPath & $sFile WEnd Case Else;files and folders While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop ;check for exclude files/folder If StringRegExp(StringRegExpReplace($sFile, "(.*?[\\/]+)*(.*?\z)", "\2"), $sTExclude) Then ContinueLoop $sFileList &= $sDelim & $sWorkPath & $sFile WEnd EndSwitch FileClose($hSearch) Next;$iFCount - next filter ;--------------- ;optional do a recursive search If $bRecursiv Then $hSearch = FileFindFirstFile($sPathItem & "*.*") If Not @error Then While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended = 0 Then ContinueLoop;bypass file (for Autoit versions > 3.3.0.0) ;check for exclude folder If StringRegExp(StringRegExpReplace($sFile, "(.*?[\\/]+)*(.*?\z)", "\2"), $sTExclude) Then ContinueLoop ;call recursive search If $iPathType = 1 Then $sTWorkPath = $sWorkPath & $sFile & "\" $sFileList &= _FileListToArrayNT($sPathItem & $sFile & "\", $sFilter, $iSearchType, $iPathType, $bRecursiv, $sExclude, 2, $sTWorkPath) WEnd FileClose($hSearch) EndIf EndIf Next;$iPCount - next path Else;If Not $sExclude For $iPCount = 1 To $aPath[0];path loop Local $sPathItem = StringStripWS($aPath[$iPCount], 3);strip leading and trailing spaces Local $sDelim = "|";reset $sDelim If StringRight($sPathItem, 1) <> "\" Then $sPathItem &= "\";ensure trailing slash ;return full-path If $iPathType = 2 Then $sDelim &= $sPathItem ;perform the search For $iFCount = 1 To $aFilter[0];Filter loop Local $FilterItem = StringStripWS($aFilter[$iFCount], 3);strip leading and trailing spaces If StringRegExp($FilterItem, "[\\/:<>|]") Then ContinueLoop;bypass filters with invalid chars $hSearch = FileFindFirstFile($sPathItem & $FilterItem) If @error Then ContinueLoop Switch $iSearchType Case 1;files Only While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended Then ContinueLoop;bypass folder $sFileList &= $sDelim & $sWorkPath & $sFile WEnd Case 2;folders Only While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended = 0 Then ContinueLoop;bypass file $sFileList &= $sDelim & $sWorkPath & $sFile WEnd Case Else;files and folders While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop $sFileList &= $sDelim & $sWorkPath & $sFile WEnd EndSwitch FileClose($hSearch) Next;$iFCount - next filter ;--------------- ;optional do a recursive search If $bRecursiv Then $hSearch = FileFindFirstFile($sPathItem & "*.*") If Not @error Then While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended = 0 Then ContinueLoop;bypass file (for Autoit versions > 3.3.0.0) ;call recursive search If $iPathType = 1 Then $sTWorkPath = $sWorkPath & $sFile & "\" $sFileList &= _FileListToArrayNT($sPathItem & $sFile & "\", $sFilter, $iSearchType, $iPathType, $bRecursiv, $sExclude, 2, $sTWorkPath) WEnd FileClose($hSearch) EndIf EndIf Next;$iPCount - next path EndIf;If $sExclude ;--------------- ;set according return value If $sFileList Then Switch $iRetFormat Case 2;return a delimited string Return $sFileList Case 0;return a 0-based array Return StringSplit(StringTrimLeft($sFileList, 1), "|", 2) Case Else;return a 1-based array Return StringSplit(StringTrimLeft($sFileList, 1), "|", 1) EndSwitch Else Return SetError(4, 4, "") EndIf EndFunc;==>_FileListToArrayNT Edit: Ahem "B" and ")" makes a smiley face, ruined the effect of my listing off reasons outline-style. I'll try A: and B: instead. Edit2:Removed writes to H: drive logfile Edited July 2, 2009 by Spiff59 Link to comment Share on other sites More sharing options...
Spiff59 Posted July 2, 2009 Share Posted July 2, 2009 (edited) I chopped up the NT version (or FileListToArrayTurbo3000Plus, as I like to call it).The test below is set to run it a single time, files-and-folders, recursion on, and forced into exclude mode.My question is about the StringRegExpReplace used a number of times to exclude files.What the heck does it do???I ran this test on my entire C: RAID array and my backup D: drive, 220,000+ files. Not once did either of the Msgbox() statements I plugged in there pop up.To repeat, what is the function of that SRER that we have in 4 places on the exclude side of the script???It never kicks in once on either of my drives.CODEexpandcollapse popup$Path = "C:" $aFiles = _FileListToArrayNT($Path, '*', 0, 2, True, '*.ini', 1) MsgBox(1,"",$aFiles[0]) Exit ;=============================================================================== Func _FileListToArrayNT($sPath = @ScriptDir, $sFilter = "*", $iSearchType = 0, $iPathType = 0, $bRecursiv = False, $sExclude = "", $iRetFormat = 1, $sWorkPath = "") Local $hSearch, $iPCount, $iFCount, $sFile, $sFileList, $sTExclude, $sTWorkPath If $sPath = -1 Or $sPath = Default Then $sPath = @ScriptDir If $sFilter = -1 Or $sFilter = Default Then $sFilter = "*" If $iSearchType = -1 Or $iSearchType = Default Then $iSearchType = 0 If $iPathType = -1 Or $iPathType = Default Then $iPathType = 0 If $bRecursiv = Default Then $bRecursiv = False If $sExclude = -1 Or $sExclude = Default Then $sExclude = "" If $iRetFormat = -1 Or $iRetFormat = Default Then $iRetFormat = 1 Local $aPath = StringSplit($sPath, ';');paths array Local $aFilter = StringSplit($sFilter, ';');filters array ;prepare $sTExclude ;strip leading and trailing spaces and spaces between semi colon delimiter $sTExclude = StringStripWS(StringRegExpReplace($sExclude, "\s*;\s*", ";"), 3) ;convert $sExclude to fit StringRegExp (not perfect but useable) $sTExclude = StringRegExpReplace($sTExclude, '([\Q\.+[^]$(){}=!\E])', '\\$1');thanks KaFu and Ascend4nt $sTExclude = StringReplace($sTExclude, "?", ".") $sTExclude = StringReplace($sTExclude, "*", ".*?") $sTExclude = "(?i)\A" & StringReplace($sTExclude, ";", "|") & "\z" For $iPCount = 1 To $aPath[0];Path loop Local $sPathItem = StringStripWS($aPath[$iPCount], 3);strip leading and trailing spaces Local $sDelim = "|";reset $sDelim If StringRight($sPathItem, 1) <> "\" Then $sPathItem &= "\";ensure trailing slash If $iPathType = 2 Then $sDelim &= $sPathItem;return full-path For $iFCount = 1 To $aFilter[0];Filter loop Local $FilterItem = StringStripWS($aFilter[$iFCount], 3);strip leading and trailing spaces If StringRegExp($FilterItem, "[\\/:<>|]") Then ContinueLoop;bypass filters with invalid chars $hSearch = FileFindFirstFile($sPathItem & $FilterItem) If @error Then ContinueLoop While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop ;check for exclude files/folder $x = StringRegExpReplace($sFile, "(.*?[\\/]+)*(.*?\z)", "\2") If $sFile <> $x Then MsgBox(1,"",$sfile & @CRLF & $x) If StringRegExp($x, $sTExclude) Then ContinueLoop $sFileList &= $sDelim & $sWorkPath & $sFile WEnd FileClose($hSearch) Next;$iFCount - next filter ;--------------- ;optional do a recursive search If $bRecursiv Then $hSearch = FileFindFirstFile($sPathItem & "*.*") If Not @error Then While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended = 0 Then ContinueLoop;bypass file (for Autoit versions > 3.3.0.0) ;check for exclude folder $x = StringRegExpReplace($sFile, "(.*?[\\/]+)*(.*?\z)", "\2") If $sFile <> $x Then MsgBox(1,"",$sfile & @CRLF & $x) If StringRegExp($x, $sTExclude) Then ContinueLoop ;call recursive search If $iPathType = 1 Then $sTWorkPath = $sWorkPath & $sFile & "\" $sFileList &= _FileListToArrayNT($sPathItem & $sFile & "\", $sFilter, $iSearchType, $iPathType, $bRecursiv, $sExclude, 2, $sTWorkPath) WEnd FileClose($hSearch) EndIf EndIf Next;$iPCount - next path ;--------------- ;set according return value If $sFileList Then Switch $iRetFormat Case 2;return a delimited string Return $sFileList Case 0;return a 0-based array Return StringSplit(StringTrimLeft($sFileList, 1), "|", 2) Case Else;return a 1-based array Return StringSplit(StringTrimLeft($sFileList, 1), "|", 1) EndSwitch Else Return SetError(4, 4, "") EndIf EndFunc;==>_FileListToArrayNTEdit: It appears it's trying to do something with forward and backward slashes that occur at the end of the string?Edit2: If the string contains a forward or backward slash, it returns only the portion of the string to the right of the last slash. Does FileFindNextFile ever return a string containing a slash??? I"m thinkng we can give the exclude side of the function a speed boost by throwing out all four of those SRER's and making the lines just:If StringRegExp($x, $sTExclude) Then ContinueLoop? Edited July 2, 2009 by Spiff59 Link to comment Share on other sites More sharing options...
BaKaMu Posted July 2, 2009 Share Posted July 2, 2009 (edited) Thanks!, that is what it didn't make sence to me. How come a script that is over 100 line longer can process faster?Thats very easy: you have less If...Then decisions cause you have made the decision once (ex: the exclude decision),so the decision-tree (i hope that are the right words) is shorter.(sometimes detours are faster)I have tested your last code:(one path with 10584 files, 1560 folders, filter="*", return files/folders, full path, recursion, with one exclusion (folder exclusion)The speed is almost fast as _FileListToArrayNT but the result is a little bit wrong_FileListToArrayNT: Sec = 35.94 , 9719 items_FileListToArrayDanny: Sec = 36.08 , 9720 itemsYour code returns the name of the excluded folder.(No criticism, just comment) ;-) :-)But i have seen a good idea in your code, the $iRunFirstTime flag for parameter checking.I will try to implement it in _FileListToArrayNT.(the drawback is, there will be another unused parameter in function, maybe i find a solution for that)So you have made a good suggestion. Edited July 2, 2009 by BaKaMu Link to comment Share on other sites More sharing options...
BaKaMu Posted July 2, 2009 Share Posted July 2, 2009 I chopped up the NT version (or FileListToArrayTurbo3000Plus, as I like to call it).My Tests:(one path with 10584 files, 1560 folders, filter="*", return files/folders, full path, recursion, with no exclusion_FileListToArrayNT: Sec = 17.27 , 12144 itemsFileListToArrayTurbo3000Plus: Sec = 27.64 , 12144 items(one path with 10584 files, 1560 folders, filter="*", return files/folders, full path, recursion, with one exclusion (folder exclusion)_FileListToArrayNT: Sec = 21.58 , 9719 itemsFileListToArrayTurbo3000Plus: Sec = 22.38 , 9719 itemsSo there isn't really a speed improvement. ;-(But i have seen a good suggestion in the code of Danny35d ($iRunFirstTime flag).I will give it a try (in case of free time)Edit2: If the string contains a forward or backward slash, it returns only the portion of the string to the right of the last slash. Does FileFindNextFile ever return a string containing a slash??? I"m thinkng we can give the exclude side of the function a speed boost by throwing out all four of those SRER's and making the lines just:If StringRegExp($x, $sTExclude) Then ContinueLoop?I will think about that. Link to comment Share on other sites More sharing options...
KaFu Posted July 2, 2009 Share Posted July 2, 2009 Hi Danny35, you'll run into a recursion issue on very (very very) large directories (4810 I believe).SmOke_N, I guess that's more a theoretical then a practical issue (5100).#699650 Â OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13)Â BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16)Â ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
BaKaMu Posted July 2, 2009 Share Posted July 2, 2009 (edited) But i have seen a good suggestion in the code of Danny35d ($iRunFirstTime flag). I will give it a try (in case of free time)Now i have implemented the suggestion of Danny35d (thanks for this advise) and to my surprise there is a significant speed improvement because now the parameter checking will be done only once in recursion: (It is even faster then my private _FileListToArrayOpt Version) Test1: (one path with 10584 files, 1560 folders, filter="*", return files/folders, full path, recursion, with no exclusion, repeat 30 times _FileListToArrayNT: Sec = 17.33 , 12144 items _FileListToArrayNT3: Sec = 16.22 , 12144 items Test2: (one path with 10584 files, 1560 folders, filter="*", return files/folders, full path, recursion, with one exclusion (folder exclusion), repeat 30 times _FileListToArrayNT: Sec = 21.52 , 9719 items _FileListToArrayNT3: Sec = 19.59 , 9719 items So this is again a step forward. The only drawback is the second "do not use" parameter $iRunFirstTime (but that maybe the cost of the advantage in speed) _FileListToArrayNT3 (or FileListToArrayUltra4000Plus, as Spiff59 would like to call it) :-) expandcollapse popup; #FUNCTION# =========================================================================================== ; Name: _FileListToArrayNT3 ; Description: full compatible _FileListToArray replacement (with greater performance and additional features) ; additional: multi-path, multi-filter, multi-exclude-filter, path format options, recursive search ; Syntax: _FileListToArrayNT3([$sPath = @ScriptDir, [$sFilter = "*", [$iSearchType, [$bRecursiv = False, [$sExclude = "", [$iRetFormat = 1]]]]]]) ; Parameter(s): $sPath = optional: Search path(s), semicolon delimited (default: @ScriptDir) ; (Example: "C:\Tmp;D:\Temp") ; $sFilter = optional: Search filter(s), semicolon delimited . Wildcards allowed. (default: "*") ; (Example: "*.exe;*.txt") ; $iSearchType = Include in search: 0 = Files and Folder, 1 = Files Only, 2 = Folders Only ; $iPathType = Returned element format: 0 = file/folder name only, 1 = relative path, 2 = full path ; $bRecursiv = optional: True: recursive search including all subdirectories ; False (default): search only in specified folder ; $sExclude = optional: Exclude filter(s), semicolon delimited. Wildcards allowed. ; (Example: "Unins*" will remove all files/folders that begin with "Unins") ; $iRetFormat = optional: return format ; 0 = one-dimensional array, 0-based ; 1 = one-dimensional array, 1-based (default) ; 2 = String ( "|" delimited) ; $sWorkPath = *** internal use only (do not use) *** ; $iRunFirstTime = *** internal use only (do not use) *** ; Requirement(s): none ; Return Value(s): on success: 1-based or 0-based array or string (dependent on $iRetFormat) ; If no data is found, @error is set (to 4, for backwards compatibility) ; Author(s): Half the AutoIt Community ; ==================================================================================================== Func _FileListToArrayNT3($sPath = @ScriptDir, $sFilter = "*", $iSearchType = 0, $iPathType = 0, $bRecursiv = False, $sExclude = "", $iRetFormat = 1, $sWorkPath = "", $iRunFirstTime = True) Local $hSearch, $iPCount, $iFCount, $sFile, $sFileList, $sTWorkPath If $iRunFirstTime Then If $sPath = -1 Or $sPath = Default Then $sPath = @ScriptDir If $sFilter = -1 Or $sFilter = Default Then $sFilter = "*" If $iSearchType = -1 Or $iSearchType = Default Then $iSearchType = 0 If $iPathType = -1 Or $iPathType = Default Then $iPathType = 0 If $bRecursiv = Default Then $bRecursiv = False If $sExclude = -1 Or $sExclude = Default Then $sExclude = "" If $iRetFormat = -1 Or $iRetFormat = Default Then $iRetFormat = 1 If $sExclude Then ;prepare $sExclude ;strip leading and trailing spaces and spaces between semi colon delimiter $sExclude = StringStripWS(StringRegExpReplace($sExclude, "\s*;\s*", ";"), 3) ;convert $sExclude to fit StringRegExp (not perfect but useable) $sExclude = StringRegExpReplace($sExclude, '([\Q\.+[^]$(){}=!\E])', '\\$1') ;thanks KaFu and Ascend4nt $sExclude = StringReplace($sExclude, "?", ".") $sExclude = StringReplace($sExclude, "*", ".*?") $sExclude = "(?i)\A" & StringReplace($sExclude, ";", "|") & "\z" EndIf ;strip leading and trailing spaces and spaces between semi colon delimiter $sPath = StringStripWS(StringRegExpReplace($sPath, "\s*;\s*", ";"), 3) $sFilter = StringStripWS(StringRegExpReplace($sFilter, "\s*;\s*", ";"), 3) $iRunFirstTime = False EndIf Local $aPath = StringSplit($sPath, ';') ;paths array Local $aFilter = StringSplit($sFilter, ';') ;filters array If $sExclude Then For $iPCount = 1 To $aPath[0] ;Path loop Local $sDelim = "|" ;reset $sDelim If StringRight($aPath[$iPCount], 1) <> "\" Then $aPath[$iPCount] &= "\" ;ensure trailing slash If $iPathType = 2 Then $sDelim &= $aPath[$iPCount] ;return full-path For $iFCount = 1 To $aFilter[0] ;Filter loop If StringRegExp($aFilter[$iFCount], "[\\/:<>|]") Then ContinueLoop ;bypass filters with invalid chars $hSearch = FileFindFirstFile($aPath[$iPCount] & $aFilter[$iFCount]) If @error Then ContinueLoop Switch $iSearchType Case 1 ;files Only While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended Then ContinueLoop ;bypass folder ;check for exclude files If StringRegExp(StringRegExpReplace($sFile, "(.*?[\\/]+)*(.*?\z)", "\2"), $sExclude) Then ContinueLoop $sFileList &= $sDelim & $sWorkPath & $sFile WEnd Case 2 ;folders Only While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended = 0 Then ContinueLoop ;bypass file ;check for exclude folder If StringRegExp(StringRegExpReplace($sFile, "(.*?[\\/]+)*(.*?\z)", "\2"), $sExclude) Then ContinueLoop $sFileList &= $sDelim & $sWorkPath & $sFile WEnd Case Else ;files and folders While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop ;check for exclude files/folder If StringRegExp(StringRegExpReplace($sFile, "(.*?[\\/]+)*(.*?\z)", "\2"), $sExclude) Then ContinueLoop $sFileList &= $sDelim & $sWorkPath & $sFile WEnd EndSwitch FileClose($hSearch) Next ;$iFCount - next filter ;--------------- ;optional do a recursive search If $bRecursiv Then $hSearch = FileFindFirstFile($aPath[$iPCount] & "*.*") If Not @error Then While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended = 0 Then ContinueLoop ;bypass file (for Autoit versions > 3.3.0.0) ;check for exclude folder If StringRegExp(StringRegExpReplace($sFile, "(.*?[\\/]+)*(.*?\z)", "\2"), $sExclude) Then ContinueLoop ;call recursive search If $iPathType = 1 Then $sTWorkPath = $sWorkPath & $sFile & "\" $sFileList &= _FileListToArrayNT3($aPath[$iPCount] & $sFile & "\", $sFilter, $iSearchType, $iPathType, $bRecursiv, $sExclude, 2, $sTWorkPath, $iRunFirstTime) WEnd FileClose($hSearch) EndIf EndIf Next ;$iPCount - next path Else ;If Not $sExclude For $iPCount = 1 To $aPath[0] ;path loop Local $sDelim = "|" ;reset $sDelim If StringRight($aPath[$iPCount], 1) <> "\" Then $aPath[$iPCount] &= "\" ;ensure trailing slash ;return full-path If $iPathType = 2 Then $sDelim &= $aPath[$iPCount] ;perform the search For $iFCount = 1 To $aFilter[0] ;Filter loop If StringRegExp($aFilter[$iFCount], "[\\/:<>|]") Then ContinueLoop ;bypass filters with invalid chars $hSearch = FileFindFirstFile($aPath[$iPCount] & $aFilter[$iFCount]) If @error Then ContinueLoop Switch $iSearchType Case 1 ;files Only While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended Then ContinueLoop ;bypass folder $sFileList &= $sDelim & $sWorkPath & $sFile WEnd Case 2 ;folders Only While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended = 0 Then ContinueLoop ;bypass file $sFileList &= $sDelim & $sWorkPath & $sFile WEnd Case Else ;files and folders While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop $sFileList &= $sDelim & $sWorkPath & $sFile WEnd EndSwitch FileClose($hSearch) Next ;$iFCount - next filter ;--------------- ;optional do a recursive search If $bRecursiv Then $hSearch = FileFindFirstFile($aPath[$iPCount] & "*.*") If Not @error Then While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended = 0 Then ContinueLoop ;bypass file (for Autoit versions > 3.3.0.0) ;call recursive search If $iPathType = 1 Then $sTWorkPath = $sWorkPath & $sFile & "\" $sFileList &= _FileListToArrayNT3($aPath[$iPCount] & $sFile & "\", $sFilter, $iSearchType, $iPathType, $bRecursiv, $sExclude, 2, $sTWorkPath, $iRunFirstTime) WEnd FileClose($hSearch) EndIf EndIf Next ;$iPCount - next path EndIf ;If $sExclude ;--------------- ;set according return value If $sFileList Then Switch $iRetFormat Case 2 ;return a delimited string Return $sFileList Case 0 ;return a 0-based array Return StringSplit(StringTrimLeft($sFileList, 1), "|", 2) Case Else ;return a 1-based array Return StringSplit(StringTrimLeft($sFileList, 1), "|", 1) EndSwitch Else Return SetError(4, 4, "") EndIf EndFunc ;==>_FileListToArrayNT3 Edited July 2, 2009 by BaKaMu Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted July 2, 2009 Moderators Share Posted July 2, 2009 SmOke_N, I guess that's more a theoretical then a practical issue (5100).#699650To be honest my curiosity got the better of me. I couldn't even create a 5000 deep sub directory (well I could, but they wouldn't open). Seems to be a 250 or so limit on them... so recursion would probably not be an issue. Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
Spiff59 Posted July 2, 2009 Share Posted July 2, 2009 (edited) Now i have implemented the suggestion of Danny35d (thanks for this advise)The only drawback is the second "do not use" parameter $iRunFirstTime (but that maybe the cost of the advantage in speed)Isn't the existing "do not use" parameter, $sTWorkPath, only populated during a recursive call? I think "If Not $sTWorkPath Then" might replace "If $iRunFirstTime Then". Maybe park a comment on the end of the test saying "; bypass recursive calls" or "; process initial call only" or something similar.About the SRER, I'd like someone to pipe up if there is a reason for it. I don't believe that FileFindNextFile ever returns a filename containing a trailing forward slash or backward slash. I'm not sure you conducted the test correctly, removing all four SRER statements and running a test with exclude enabled showed a major speed increase for me, consistantly.Edit: With these latest additions, I'm now liking: _FileListToArrayTurbo4000PlusWithPowerboost() Edited July 2, 2009 by Spiff59 Link to comment Share on other sites More sharing options...
BaKaMu Posted July 2, 2009 Share Posted July 2, 2009 Isn't the existing "do not use" parameter, $sTWorkPath, only populated during a recursive call? I think "If Not $sTWorkPath Then" might replace "If $iRunFirstTime Then". Maybe park a comment on the end of the test saying "; bypass recursive calls" or "; process initial call only" or something similar.No, it's only used if $iPathType = 1 (relative)--> If $iPathType = 1 Then $sTWorkPath = $sWorkPath & $sFile & "\" <--, it's your code ;-)About the SRER, I'd like someone to pipe up if there is a reason for it. I don't believe that FileFindNextFile ever returns a filename containing a trailing forward slash or backward slash. I'm not sure you conducted the test correctly, removing all four SRER statements and running a test with exclude enabled showed a major speed increase for me, consistantly.I don't understand your question. Witch StringRegExpReplace do you mean? There are some for different purposes.Edit: With these latest additions, I'm now liking: _FileListToArrayTurbo4000PlusWithPowerboost()Yes that's really good, this drives jpm mad ;-) Link to comment Share on other sites More sharing options...
Spiff59 Posted July 2, 2009 Share Posted July 2, 2009 (edited) No, it's only used if $iPathType = 1 (relative) --> If $iPathType = 1 Then $sTWorkPath = $sWorkPath & $sFile & "\" <--, it's your code ;-) Ahem, nice weather today, huh? That's what I get for just spitting things out. Yes, it's only populated on recursive calls, but yes, also, it's only populated when PathType = 1 Which StringRegExpReplace do you mean? I think all 4 of these lines: If StringRegExp(StringRegExpReplace($sFile, "(.*?[\\/]+)*(.*?\z)", "\2"), $sTExclude) Then ContinueLoop may only need to be: If StringRegExp($sFile, $sTExclude) Then ContinueLoop Edit: I just ran the test here at work. So, at this point scanning my entire C: and D: drives at home, and this C: drive at work have yet to encounter one instance where those SRER statements made a single modification. Edit2: Post 123 is not a benchmark but a test run. It forces exclusion, so isn't going to benchmark against a non-exclude run. It's simple meant to demonstrate, by not generating any MsgBox() windows (except the final file count), that the 4 exclude SRER's never do anything. Edited July 2, 2009 by Spiff59 Link to comment Share on other sites More sharing options...
BaKaMu Posted July 2, 2009 Share Posted July 2, 2009 (edited) If StringRegExp(StringRegExpReplace($sFile, "(.*?[\\/]+)*(.*?\z)", "\2"), $sTExclude) Then ContinueLoop If StringRegExp($sFile, $sTExclude) Then ContinueLoopFantastic, you have won the jackpot! My Test (quick and dirty, has to be tested more often) (one path with 10584 files, 1560 folders, filter="*", return files/folders, full path, recursion, with one exclusion (folder exclusion), repeat 30 times): _FileListToArrayNT3: Sec = 19.51 , 9719 items _FileListToArrayNT4: Sec = 14.69 , 9719 items , oh that's nice _FileListToArrayNT4 (or _FileListToArrayTurbo4000PlusWithUltraPowerboostbySpiff59) expandcollapse popup; #FUNCTION# =========================================================================================== ; Name: _FileListToArrayNT4 ; Description: full compatible _FileListToArray replacement (with greater performance and additional features) ; additional: multi-path, multi-filter, multi-exclude-filter, path format options, recursive search ; Syntax: _FileListToArrayNT4([$sPath = @ScriptDir, [$sFilter = "*", [$iSearchType, [$bRecursiv = False, [$sExclude = "", [$iRetFormat = 1]]]]]]) ; Parameter(s): $sPath = optional: Search path(s), semicolon delimited (default: @ScriptDir) ; (Example: "C:\Tmp;D:\Temp") ; $sFilter = optional: Search filter(s), semicolon delimited . Wildcards allowed. (default: "*") ; (Example: "*.exe;*.txt") ; $iSearchType = Include in search: 0 = Files and Folder, 1 = Files Only, 2 = Folders Only ; $iPathType = Returned element format: 0 = file/folder name only, 1 = relative path, 2 = full path ; $bRecursiv = optional: True: recursive search including all subdirectories ; False (default): search only in specified folder ; $sExclude = optional: Exclude filter(s), semicolon delimited. Wildcards allowed. ; (Example: "Unins*" will remove all files/folders that begin with "Unins") ; $iRetFormat = optional: return format ; 0 = one-dimensional array, 0-based ; 1 = one-dimensional array, 1-based (default) ; 2 = String ( "|" delimited) ; $sWorkPath = *** internal use only (do not use) *** ; $bRunFirstTime = *** internal use only (do not use) *** ; Requirement(s): none ; Return Value(s): on success: 1-based or 0-based array or string (dependent on $iRetFormat) ; If no data is found, @error is set (to 4, for backwards compatibility) ; Author(s): Half the AutoIt Community ; ==================================================================================================== Func _FileListToArrayNT4($sPath = @ScriptDir, $sFilter = "*", $iSearchType = 0, $iPathType = 0, $bRecursiv = False, $sExclude = "", $iRetFormat = 1, $sWorkPath = "", $bRunFirstTime = True) Local $hSearch, $iPCount, $iFCount, $sFile, $sFileList, $sTWorkPath If $bRunFirstTime Then If $sPath = -1 Or $sPath = Default Then $sPath = @ScriptDir If $sFilter = -1 Or $sFilter = Default Then $sFilter = "*" If $iSearchType = -1 Or $iSearchType = Default Then $iSearchType = 0 If $iPathType = -1 Or $iPathType = Default Then $iPathType = 0 If $bRecursiv = Default Then $bRecursiv = False If $sExclude = -1 Or $sExclude = Default Then $sExclude = "" If $iRetFormat = -1 Or $iRetFormat = Default Then $iRetFormat = 1 If $sExclude Then ;prepare $sExclude ;strip leading and trailing spaces and spaces between semi colon delimiter $sExclude = StringStripWS(StringRegExpReplace($sExclude, "\s*;\s*", ";"), 3) ;convert $sExclude to fit StringRegExp (not perfect but useable) $sExclude = StringRegExpReplace($sExclude, '([\Q\.+[^]$(){}=!\E])', '\\$1') ;thanks KaFu and Ascend4nt $sExclude = StringReplace($sExclude, "?", ".") $sExclude = StringReplace($sExclude, "*", ".*?") $sExclude = "(?i)\A" & StringReplace($sExclude, ";", "|") & "\z" EndIf ;strip leading and trailing spaces and spaces between semi colon delimiter $sPath = StringStripWS(StringRegExpReplace($sPath, "\s*;\s*", ";"), 3) $sFilter = StringStripWS(StringRegExpReplace($sFilter, "\s*;\s*", ";"), 3) $bRunFirstTime = False EndIf Local $aPath = StringSplit($sPath, ';', 1) ;paths array Local $aFilter = StringSplit($sFilter, ';', 1) ;filters array If $sExclude Then For $iPCount = 1 To $aPath[0] ;Path loop Local $sDelim = "|" ;reset $sDelim If StringRight($aPath[$iPCount], 1) <> "\" Then $aPath[$iPCount] &= "\" ;ensure trailing slash If $iPathType = 2 Then $sDelim &= $aPath[$iPCount] ;return full-path For $iFCount = 1 To $aFilter[0] ;Filter loop If StringRegExp($aFilter[$iFCount], "[\\/:<>|]") Then ContinueLoop ;bypass filters with invalid chars $hSearch = FileFindFirstFile($aPath[$iPCount] & $aFilter[$iFCount]) If @error Then ContinueLoop Switch $iSearchType Case 1 ;files Only While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended Then ContinueLoop ;bypass folder ;check for exclude files If StringRegExp($sFile, $sExclude) Then ContinueLoop $sFileList &= $sDelim & $sWorkPath & $sFile WEnd Case 2 ;folders Only While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended = 0 Then ContinueLoop ;bypass file ;check for exclude folder If StringRegExp($sFile, $sExclude) Then ContinueLoop $sFileList &= $sDelim & $sWorkPath & $sFile WEnd Case Else ;files and folders While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop ;check for exclude files/folder If StringRegExp($sFile, $sExclude) Then ContinueLoop $sFileList &= $sDelim & $sWorkPath & $sFile WEnd EndSwitch FileClose($hSearch) Next ;$iFCount - next filter ;--------------- ;optional do a recursive search If $bRecursiv Then $hSearch = FileFindFirstFile($aPath[$iPCount] & "*.*") If Not @error Then While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended = 0 Then ContinueLoop ;bypass file (for Autoit versions > 3.3.0.0) ;check for exclude folder If StringRegExp($sFile, $sExclude) Then ContinueLoop ;call recursive search If $iPathType = 1 Then $sTWorkPath = $sWorkPath & $sFile & "\" $sFileList &= _FileListToArrayNT4($aPath[$iPCount] & $sFile & "\", $sFilter, $iSearchType, $iPathType, $bRecursiv, $sExclude, 2, $sTWorkPath, $bRunFirstTime) WEnd FileClose($hSearch) EndIf EndIf Next ;$iPCount - next path Else ;If Not $sExclude For $iPCount = 1 To $aPath[0] ;path loop Local $sDelim = "|" ;reset $sDelim If StringRight($aPath[$iPCount], 1) <> "\" Then $aPath[$iPCount] &= "\" ;ensure trailing slash ;return full-path If $iPathType = 2 Then $sDelim &= $aPath[$iPCount] ;perform the search For $iFCount = 1 To $aFilter[0] ;Filter loop If StringRegExp($aFilter[$iFCount], "[\\/:<>|]") Then ContinueLoop ;bypass filters with invalid chars $hSearch = FileFindFirstFile($aPath[$iPCount] & $aFilter[$iFCount]) If @error Then ContinueLoop Switch $iSearchType Case 1 ;files Only While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended Then ContinueLoop ;bypass folder $sFileList &= $sDelim & $sWorkPath & $sFile WEnd Case 2 ;folders Only While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended = 0 Then ContinueLoop ;bypass file $sFileList &= $sDelim & $sWorkPath & $sFile WEnd Case Else ;files and folders While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop $sFileList &= $sDelim & $sWorkPath & $sFile WEnd EndSwitch FileClose($hSearch) Next ;$iFCount - next filter ;--------------- ;optional do a recursive search If $bRecursiv Then $hSearch = FileFindFirstFile($aPath[$iPCount] & "*.*") If Not @error Then While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended = 0 Then ContinueLoop ;bypass file (for Autoit versions > 3.3.0.0) ;call recursive search If $iPathType = 1 Then $sTWorkPath = $sWorkPath & $sFile & "\" $sFileList &= _FileListToArrayNT4($aPath[$iPCount] & $sFile & "\", $sFilter, $iSearchType, $iPathType, $bRecursiv, $sExclude, 2, $sTWorkPath, $bRunFirstTime) WEnd FileClose($hSearch) EndIf EndIf Next ;$iPCount - next path EndIf ;If $sExclude ;--------------- ;set according return value If $sFileList Then Switch $iRetFormat Case 2 ;return a delimited string Return $sFileList Case 0 ;return a 0-based array Return StringSplit(StringTrimLeft($sFileList, 1), "|", 2) Case Else ;return a 1-based array Return StringSplit(StringTrimLeft($sFileList, 1), "|", 1) EndSwitch Else Return SetError(4, 4, "") EndIf EndFunc ;==>_FileListToArrayNT4 Edited July 2, 2009 by BaKaMu Link to comment Share on other sites More sharing options...
Spiff59 Posted July 2, 2009 Share Posted July 2, 2009 (edited) _FileListToArrayNT4 (or _FileListToArrayTurbo4000PlusWithUltraPowerboostbySpiff59)I don't need my name up in lights, but I do think we're missing a "Pro" in there, so:_FileListToArrayTurbo4000PlusProWithUltraPowerboost BTW: Have you tried running Post #123 against the biggest hard drive you have? Does it make it to the file-count message without any other messages? I'm almost positive that FileFindNextFile never returns a string with a trailing slash and that the last change stripping off the SRER's is valid. Edited July 2, 2009 by Spiff59 Link to comment Share on other sites More sharing options...
BaKaMu Posted July 2, 2009 Share Posted July 2, 2009 (edited) I don't need my name up in lights, but I do think we're missing a "Pro" in there, so: _FileListToArrayTurbo4000PlusProWithUltraPowerboostAgree :-) BTW: Have you tried running Post #123 against the biggest hard drive you have? Does it make it to the file-count message without any other messages? I'm almost positive that FileFindNextFile never returns a string with a trailing slash and that the last change stripping off the SRER's is valid.No, but i belief that stripping off the SRER's is valid. This StringRegExp(StringRegExpReplace($sFile, "(.*?[\\/]+)*(.*?\z)", "\2"), $sExclude) combination splits a full path in path and file/folder name and then compares to $sExclude. FileFindNextFile only returns file or folder name so stripping off the SRER's can not be invalid (theoretical). Hopefully we have reached the limit now. ;-) After all i have to relax a little bit. Edited July 2, 2009 by BaKaMu Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted July 2, 2009 Moderators Share Posted July 2, 2009 Without going through every piece of code you've written here. Have ya'll tried just condition statements without ContinueLoop overhead? I don't know how much has changed with it, but I've found in the past that: If @error = 0 Then ;Condition EndIf Is much faster for large loops than: If @error Then ContinueLoop Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
BaKaMu Posted July 2, 2009 Share Posted July 2, 2009 (edited) If @error = 0 Then ... Condition ... EndIf Is much faster for large loops than: If @error Then ContinueLoopGood idea an i have made some tests with this suggestion. Yes: If Condition Then ... EndIf is faster then If Condition Then ContinueLoop But: If the condition is a negation (ex Not @error or Not StringRegExp(...)) then it is slower. So in _FileListToArrayNT5 i have paid attention to not using negation. And Voila, there is a little speed improvement. (but really little compared to Spiff59 boosting) Test1 (one path with 10584 files, 1560 folders, filter="*", return files/folders, full path, recursion, with no exclusion, repeat 30 times): _FileListToArrayNT4: Sec = 16.21 , 12144 items _FileListToArrayNT5: Sec = 16.01 , 12144 items Test2 (one path with 10584 files, 1560 folders, filter="*", return files/folders, full path, recursion, with one exclusion (folder exclusion), repeat 30 times): _FileListToArrayNT4: Sec = 14.71 , 9719 items _FileListToArrayNT5: Sec = 14.65 , 9719 items I thought we have reached the limit now, but obviously not. Thank you SmOke_N ;-) _FileListToArrayNT5 (@Spiff59: _FileListToArrayTurbo4000PlusProWithMoreUltraPowerboost) expandcollapse popup; #FUNCTION# =========================================================================================== ; Name: _FileListToArrayNT5 ; Description: full compatible _FileListToArray replacement (with greater performance and additional features) ; additional: multi-path, multi-filter, multi-exclude-filter, path format options, recursive search ; Syntax: _FileListToArrayNT5([$sPath = @ScriptDir, [$sFilter = "*", [$iSearchType, [$bRecursiv = False, [$sExclude = "", [$iRetFormat = 1]]]]]]) ; Parameter(s): $sPath = optional: Search path(s), semicolon delimited (default: @ScriptDir) ; (Example: "C:\Tmp;D:\Temp") ; $sFilter = optional: Search filter(s), semicolon delimited . Wildcards allowed. (default: "*") ; (Example: "*.exe;*.txt") ; $iSearchType = Include in search: 0 = Files and Folder, 1 = Files Only, 2 = Folders Only ; $iPathType = Returned element format: 0 = file/folder name only, 1 = relative path, 2 = full path ; $bRecursiv = optional: True: recursive search including all subdirectories ; False (default): search only in specified folder ; $sExclude = optional: Exclude filter(s), semicolon delimited. Wildcards allowed. ; (Example: "Unins*" will remove all files/folders that begin with "Unins") ; $iRetFormat = optional: return format ; 0 = one-dimensional array, 0-based ; 1 = one-dimensional array, 1-based (default) ; 2 = String ( "|" delimited) ; $sWorkPath = *** internal use only (do not use) *** ; $bRunFirstTime = *** internal use only (do not use) *** ; Requirement(s): none ; Return Value(s): on success: 1-based or 0-based array or string (dependent on $iRetFormat) ; If no data is found, @error is set (to 4, for backwards compatibility) ; Author(s): Half the AutoIt Community ; ==================================================================================================== Func _FileListToArrayNT5($sPath = @ScriptDir, $sFilter = "*", $iSearchType = 0, $iPathType = 0, $bRecursiv = False, $sExclude = "", $iRetFormat = 1, $sWorkPath = "", $bRunFirstTime = True) Local $hSearch, $iPCount, $iFCount, $sFile, $sFileList, $sTWorkPath If $bRunFirstTime Then If $sPath = -1 Or $sPath = Default Then $sPath = @ScriptDir If $sFilter = -1 Or $sFilter = Default Then $sFilter = "*" If $iSearchType = -1 Or $iSearchType = Default Then $iSearchType = 0 If $iPathType = -1 Or $iPathType = Default Then $iPathType = 0 If $bRecursiv = Default Then $bRecursiv = False If $sExclude = -1 Or $sExclude = Default Then $sExclude = "" If $iRetFormat = -1 Or $iRetFormat = Default Then $iRetFormat = 1 If $sExclude Then ;prepare $sExclude ;strip leading and trailing spaces and spaces between semi colon delimiter $sExclude = StringStripWS(StringRegExpReplace($sExclude, "\s*;\s*", ";"), 3) ;convert $sExclude to fit StringRegExp (not perfect but useable) $sExclude = StringRegExpReplace($sExclude, '([\Q\.+[^]$(){}=!\E])', '\\$1') ;thanks KaFu and Ascend4nt $sExclude = StringReplace($sExclude, "?", ".") $sExclude = StringReplace($sExclude, "*", ".*?") $sExclude = "(?i)\A" & StringReplace($sExclude, ";", "|") & "\z" EndIf ;strip leading and trailing spaces and spaces between semi colon delimiter $sPath = StringStripWS(StringRegExpReplace($sPath, "\s*;\s*", ";"), 3) $sFilter = StringStripWS(StringRegExpReplace($sFilter, "\s*;\s*", ";"), 3) $bRunFirstTime = False EndIf Local $aPath = StringSplit($sPath, ';', 1) ;paths array Local $aFilter = StringSplit($sFilter, ';', 1) ;filters array If $sExclude Then For $iPCount = 1 To $aPath[0] ;Path loop Local $sDelim = "|" ;reset $sDelim If StringRight($aPath[$iPCount], 1) <> "\" Then $aPath[$iPCount] &= "\" ;ensure trailing slash If $iPathType = 2 Then $sDelim &= $aPath[$iPCount] ;return full-path For $iFCount = 1 To $aFilter[0] ;Filter loop If StringRegExp($aFilter[$iFCount], "[\\/:<>|]") Then ContinueLoop ;bypass filters with invalid chars $hSearch = FileFindFirstFile($aPath[$iPCount] & $aFilter[$iFCount]) If @error Then ContinueLoop Switch $iSearchType Case 1 ;files Only While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended Then ContinueLoop ;bypass folder ;check for exclude files If StringRegExp($sFile, $sExclude) Then ContinueLoop $sFileList &= $sDelim & $sWorkPath & $sFile WEnd Case 2 ;folders Only While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended Then ;bypass file ;check for exclude folder If StringRegExp($sFile, $sExclude) Then ContinueLoop $sFileList &= $sDelim & $sWorkPath & $sFile EndIf WEnd Case Else ;files and folders While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop ;check for exclude files/folder If StringRegExp($sFile, $sExclude) Then ContinueLoop $sFileList &= $sDelim & $sWorkPath & $sFile WEnd EndSwitch FileClose($hSearch) Next ;$iFCount - next filter ;--------------- ;optional do a recursive search If $bRecursiv Then $hSearch = FileFindFirstFile($aPath[$iPCount] & "*.*") If Not @error Then While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended Then ;bypass file (for Autoit versions > 3.3.0.0) ;check for exclude folder If StringRegExp($sFile, $sExclude) Then ContinueLoop ;call recursive search If $iPathType = 1 Then $sTWorkPath = $sWorkPath & $sFile & "\" $sFileList &= _FileListToArrayNT5($aPath[$iPCount] & $sFile & "\", $sFilter, $iSearchType, $iPathType, $bRecursiv, $sExclude, 2, $sTWorkPath, $bRunFirstTime) EndIf WEnd FileClose($hSearch) EndIf EndIf Next ;$iPCount - next path Else ;If Not $sExclude For $iPCount = 1 To $aPath[0] ;path loop Local $sDelim = "|" ;reset $sDelim If StringRight($aPath[$iPCount], 1) <> "\" Then $aPath[$iPCount] &= "\" ;ensure trailing slash ;return full-path If $iPathType = 2 Then $sDelim &= $aPath[$iPCount] ;perform the search For $iFCount = 1 To $aFilter[0] ;Filter loop If StringRegExp($aFilter[$iFCount], "[\\/:<>|]") Then ContinueLoop ;bypass filters with invalid chars $hSearch = FileFindFirstFile($aPath[$iPCount] & $aFilter[$iFCount]) If @error Then ContinueLoop Switch $iSearchType Case 1 ;files Only While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended Then ContinueLoop ;bypass folder $sFileList &= $sDelim & $sWorkPath & $sFile WEnd Case 2 ;folders Only While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended Then ;bypass file $sFileList &= $sDelim & $sWorkPath & $sFile EndIf WEnd Case Else ;files and folders While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop $sFileList &= $sDelim & $sWorkPath & $sFile WEnd EndSwitch FileClose($hSearch) Next ;$iFCount - next filter ;--------------- ;optional do a recursive search If $bRecursiv Then $hSearch = FileFindFirstFile($aPath[$iPCount] & "*.*") If Not @error Then While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended Then ;bypass file (for Autoit versions > 3.3.0.0) ;call recursive search If $iPathType = 1 Then $sTWorkPath = $sWorkPath & $sFile & "\" $sFileList &= _FileListToArrayNT5($aPath[$iPCount] & $sFile & "\", $sFilter, $iSearchType, $iPathType, $bRecursiv, $sExclude, 2, $sTWorkPath, $bRunFirstTime) EndIf WEnd FileClose($hSearch) EndIf EndIf Next ;$iPCount - next path EndIf ;If $sExclude ;--------------- ;set according return value If $sFileList Then Switch $iRetFormat Case 2 ;return a delimited string Return $sFileList Case 0 ;return a 0-based array Return StringSplit(StringTrimLeft($sFileList, 1), "|", 2) Case Else ;return a 1-based array Return StringSplit(StringTrimLeft($sFileList, 1), "|", 1) EndSwitch Else Return SetError(4, 4, "") EndIf EndFunc ;==>_FileListToArrayNT5 Edited July 2, 2009 by BaKaMu Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted July 2, 2009 Moderators Share Posted July 2, 2009 (edited) Good idea an i have made some tests with this suggestion. Yes: If Condition Then ... EndIf is faster then If Condition Then ContinueLoop But: If the condition is a negation (ex Not @error or Not StringRegExp(...)) then it is slower. So in _FileListToArrayNT5 i have paid attention to not using negation. And Voila, there is a little speed improvement. (but really little compared to Spiff59 boosting) Test1 (one path with 10584 files, 1560 folders, filter="*", return files/folders, full path, recursion, with no exclusion, repeat 30 times): _FileListToArrayNT4: Sec = 16.21 , 12144 items _FileListToArrayNT5: Sec = 16.01 , 12144 items Test2 (one path with 10584 files, 1560 folders, filter="*", return files/folders, full path, recursion, with one exclusion (folder exclusion), repeat 30 times): _FileListToArrayNT4: Sec = 14.71 , 9719 items _FileListToArrayNT5: Sec = 14.65 , 9719 items I thought we have reached the limit now, but obviously not. Thank you SmOke_N ;-) _FileListToArrayNT5 (@Spiff59: _FileListToArrayTurbo4000PlusProWithMoreUltraPowerboost) This is actually what I had in mind:expandcollapse popup; #FUNCTION# =========================================================================================== ; Name: _FileListToArrayNT5 ; Description: full compatible _FileListToArray replacement (with greater performance and additional features) ; additional: multi-path, multi-filter, multi-exclude-filter, path format options, recursive search ; Syntax: _FileListToArrayNT5([$sPath = @ScriptDir, [$sFilter = "*", [$iSearchType, [$bRecursiv = False, [$sExclude = "", [$iRetFormat = 1]]]]]]) ; Parameter(s): $sPath = optional: Search path(s), semicolon delimited (default: @ScriptDir) ; (Example: "C:\Tmp;D:\Temp") ; $sFilter = optional: Search filter(s), semicolon delimited . Wildcards allowed. (default: "*") ; (Example: "*.exe;*.txt") ; $iSearchType = Include in search: 0 = Files and Folder, 1 = Files Only, 2 = Folders Only ; $iPathType = Returned element format: 0 = file/folder name only, 1 = relative path, 2 = full path ; $bRecursiv = optional: True: recursive search including all subdirectories ; False (default): search only in specified folder ; $sExclude = optional: Exclude filter(s), semicolon delimited. Wildcards allowed. ; (Example: "Unins*" will remove all files/folders that begin with "Unins") ; $iRetFormat = optional: return format ; 0 = one-dimensional array, 0-based ; 1 = one-dimensional array, 1-based (default) ; 2 = String ( "|" delimited) ; $sWorkPath = *** internal use only (do not use) *** ; $bRunFirstTime = *** internal use only (do not use) *** ; Requirement(s): none ; Return Value(s): on success: 1-based or 0-based array or string (dependent on $iRetFormat) ; If no data is found, @error is set (to 4, for backwards compatibility) ; Author(s): Half the AutoIt Community ; ==================================================================================================== Func _FileListToArrayNT5($sPath = @ScriptDir, $sFilter = "*", $iSearchType = 0, $iPathType = 0, $bRecursiv = False, $sExclude = "", $iRetFormat = 1, $sWorkPath = "", $bRunFirstTime = True) Local $hSearch, $iPCount, $iFCount, $sFile, $sFileList, $sTWorkPath If $bRunFirstTime Then If $sPath = -1 Or $sPath = Default Then $sPath = @ScriptDir If $sFilter = -1 Or $sFilter = Default Then $sFilter = "*" If $iSearchType = -1 Or $iSearchType = Default Then $iSearchType = 0 If $iPathType = -1 Or $iPathType = Default Then $iPathType = 0 If $bRecursiv = Default Then $bRecursiv = False If $sExclude = -1 Or $sExclude = Default Then $sExclude = "" If $iRetFormat = -1 Or $iRetFormat = Default Then $iRetFormat = 1 If $sExclude Then ;prepare $sExclude ;strip leading and trailing spaces and spaces between semi colon delimiter $sExclude = StringStripWS(StringRegExpReplace($sExclude, "\s*;\s*", ";"), 3) ;convert $sExclude to fit StringRegExp (not perfect but useable) $sExclude = StringRegExpReplace($sExclude, '([\Q\.+[^]$(){}=!\E])', '\\$1') ;thanks KaFu and Ascend4nt $sExclude = StringReplace($sExclude, "?", ".") $sExclude = StringReplace($sExclude, "*", ".*?") $sExclude = "(?i)\A" & StringReplace($sExclude, ";", "|") & "\z" EndIf ;strip leading and trailing spaces and spaces between semi colon delimiter $sPath = StringStripWS(StringRegExpReplace($sPath, "\s*;\s*", ";"), 3) $sFilter = StringStripWS(StringRegExpReplace($sFilter, "\s*;\s*", ";"), 3) $bRunFirstTime = False EndIf Local $aPath = StringSplit($sPath, ';', 1) ;paths array Local $aFilter = StringSplit($sFilter, ';', 1) ;filters array If $sExclude Then For $iPCount = 1 To $aPath[0] ;Path loop Local $sDelim = "|" ;reset $sDelim If StringRight($aPath[$iPCount], 1) <> "\" Then $aPath[$iPCount] &= "\" ;ensure trailing slash If $iPathType = 2 Then $sDelim &= $aPath[$iPCount] ;return full-path For $iFCount = 1 To $aFilter[0] ;Filter loop If StringRegExp($aFilter[$iFCount], "[\\/:<>|]") = 0 Then ;bypass filters with invalid chars $hSearch = FileFindFirstFile($aPath[$iPCount] & $aFilter[$iFCount]) If @error Then ContinueLoop Switch $iSearchType Case 1 ;files Only While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended = 0 Then ;check for exclude files If StringRegExp($sFile, $sExclude) = 0 Then $sFileList &= $sDelim & $sWorkPath & $sFile EndIf EndIf WEnd Case 2 ;folders Only While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended Then ;bypass file ;check for exclude folder If StringRegExp($sFile, $sExclude) = 0 Then $sFileList &= $sDelim & $sWorkPath & $sFile EndIf EndIf WEnd Case Else ;files and folders While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop ;check for exclude files/folder If StringRegExp($sFile, $sExclude) = 0 Then $sFileList &= $sDelim & $sWorkPath & $sFile EndIf WEnd EndSwitch FileClose($hSearch) EndIf Next ;$iFCount - next filter ;--------------- ;optional do a recursive search If $bRecursiv Then $hSearch = FileFindFirstFile($aPath[$iPCount] & "*.*") If Not @error Then While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended Then ;bypass file (for Autoit versions > 3.3.0.0) ;check for exclude folder If StringRegExp($sFile, $sExclude) = 0 Then ;call recursive search If $iPathType = 1 Then $sTWorkPath = $sWorkPath & $sFile & "\" $sFileList &= _FileListToArrayNT5($aPath[$iPCount] & $sFile & "\", $sFilter, $iSearchType, $iPathType, $bRecursiv, $sExclude, 2, $sTWorkPath, $bRunFirstTime) EndIf EndIf WEnd FileClose($hSearch) EndIf EndIf Next ;$iPCount - next path Else ;If Not $sExclude For $iPCount = 1 To $aPath[0] ;path loop Local $sDelim = "|" ;reset $sDelim If StringRight($aPath[$iPCount], 1) <> "\" Then $aPath[$iPCount] &= "\" ;ensure trailing slash ;return full-path If $iPathType = 2 Then $sDelim &= $aPath[$iPCount] ;perform the search For $iFCount = 1 To $aFilter[0] ;Filter loop If StringRegExp($aFilter[$iFCount], "[\\/:<>|]") = 0 Then $hSearch = FileFindFirstFile($aPath[$iPCount] & $aFilter[$iFCount]) If @error Then ContinueLoop Switch $iSearchType Case 1 ;files Only While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended = 0 Then ;bypass folder $sFileList &= $sDelim & $sWorkPath & $sFile EndIf WEnd Case 2 ;folders Only While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended Then ;bypass file $sFileList &= $sDelim & $sWorkPath & $sFile EndIf WEnd Case Else ;files and folders While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop $sFileList &= $sDelim & $sWorkPath & $sFile WEnd EndSwitch FileClose($hSearch) EndIf Next ;$iFCount - next filter ;--------------- ;optional do a recursive search If $bRecursiv Then $hSearch = FileFindFirstFile($aPath[$iPCount] & "*.*") If Not @error Then While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If @extended Then ;bypass file (for Autoit versions > 3.3.0.0) ;call recursive search If $iPathType = 1 Then $sTWorkPath = $sWorkPath & $sFile & "\" $sFileList &= _FileListToArrayNT5($aPath[$iPCount] & $sFile & "\", $sFilter, $iSearchType, $iPathType, $bRecursiv, $sExclude, 2, $sTWorkPath, $bRunFirstTime) EndIf WEnd FileClose($hSearch) EndIf EndIf Next ;$iPCount - next path EndIf ;If $sExclude ;--------------- ;set according return value If $sFileList Then Switch $iRetFormat Case 2 ;return a delimited string Return $sFileList Case 0 ;return a 0-based array Return StringSplit(StringTrimLeft($sFileList, 1), "|", 2) Case Else ;return a 1-based array Return StringSplit(StringTrimLeft($sFileList, 1), "|", 1) EndSwitch Else Return SetError(4, 4, "") EndIf EndFunc ;==>_FileListToArrayNT5(Nothing checked other than ContinueLoop) Edit: Am I calling this the wrong way?$a = _FileListToArrayNT5(@WindowsDir, "*", 0, 0, True) If IsArray($a) Then ConsoleWrite($a[0] & @CRLF)? There should be 5400+ files, and it only returns 300? Edit2: Nevermind, I made a "Beta" mistake .... Edited July 2, 2009 by SmOke_N Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
BaKaMu Posted July 2, 2009 Share Posted July 2, 2009 This is actually what I had in mind:(Nothing checked other than ContinueLoop)That's the trick: Sometimes --> If Condition Then ... EndIf <-- is faster and sometimes --> If Condition Then ContinueLoop <--(depends on condition: conditions with negation or value checking make instruction slower,so the advantage of --> If ... Then ... EndIf <-- will be nullified.(i know that's hard to belief) Link to comment Share on other sites More sharing options...
Spiff59 Posted July 2, 2009 Share Posted July 2, 2009 (edited) I think I'm about done! Just a few more things... 1. The block of parameter edit statements don't quite function as well as they could. I worked on them a little and came up with some changes. The test program below demonstrates the changes. Run that, the window titles describe pretty well what you're seeing. I think the new behavior is preferable and would like to see the old block of edits statements replaced with the new. (The main improvements are in the handling of empty strings, $bRecursive, and garbage data) CODEexpandcollapse popup#include <GuiListView.au3> ; If StringRegExp($sPath, "(?i)Default$|-1|^$") Then $sPath = @ScriptDir ; The above worked to peg "Default", "-1" and "", but... is much slower! Global $t1, $t2, $comment = "No parms specified" _TestNT5() $comment = "Empty strings" $sPath = "" $sFilter = "" $iSearchType = "" $iPathType = "" $bRecursive = "" $sExclude = "" $iRetFormat = "" _TestNT5($sPath, $sFilter, $iSearchType, $iPathType, $bRecursive, $sExclude, $iRetFormat) $comment = "Everything is Default" $sPath = Default $sFilter = Default $iSearchType = Default $iPathType = Default $bRecursive = Default $sExclude = Default $iRetFormat = Default _TestNT5($sPath, $sFilter, $iSearchType, $iPathType, $bRecursive, $sExclude, $iRetFormat) $comment = "Everything is True" $sPath = True $sFilter = True $iSearchType = True $iPathType = True $bRecursive = True $sExclude = True $iRetFormat = True _TestNT5($sPath, $sFilter, $iSearchType, $iPathType, $bRecursive, $sExclude, $iRetFormat) $comment = "Everything is False" $sPath = False $sFilter = False $iSearchType = False $iPathType = False $bRecursive = False $sExclude = False $iRetFormat = False _TestNT5($sPath, $sFilter, $iSearchType, $iPathType, $bRecursive, $sExclude, $iRetFormat) $comment = "Everything is 0" $sPath = 0 $sFilter = 0 $iSearchType = 0 $iPathType = 0 $bRecursive = 0 $sExclude = 0 $iRetFormat = 0 _TestNT5($sPath, $sFilter, $iSearchType, $iPathType, $bRecursive, $sExclude, $iRetFormat) $comment = "Everything is 1" $sPath = 1 $sFilter = 1 $iSearchType = 1 $iPathType = 1 $bRecursive = 1 $sExclude = 1 $iRetFormat = 1 _TestNT5($sPath, $sFilter, $iSearchType, $iPathType, $bRecursive, $sExclude, $iRetFormat) $comment = "Everything is -1" $sPath = -1 $sFilter = -1 $iSearchType = -1 $iPathType = -1 $bRecursive = -1 $sExclude = -1 $iRetFormat = -1 _TestNT5($sPath, $sFilter, $iSearchType, $iPathType, $bRecursive, $sExclude, $iRetFormat) $comment = "All Garbage" $sPath = "Nothin' but garbage" $sFilter = "xyzzy" $iSearchType = "plugh" $iPathType = "plover" $bRecursive = "42" $sExclude = "xyz" $iRetFormat = "123" _TestNT5($sPath, $sFilter, $iSearchType, $iPathType, $bRecursive, $sExclude, $iRetFormat) MsgBox(1,"1000 iterations in milliseconds","Old edits: " & $t1 & @CRLF & "New edits: " & $t2 & @CRLF & "Difference per call in millionths of a second: " & Int($t2 - $t1)) Exit ;=============================================================================== Func _TestNT5($sPath = @ScriptDir, $sFilter = "*", $iSearchType = 0, $iPathType = 0, $bRecursive = False, $sExclude = "", $iRetFormat = 1) GuiCreate("Row 1: Parms in Row 2: Old edits Row 3: New edits (" & $comment & ")", 800, 110) $ListView = GuiCtrlCreateListView("$sPath|$sFilter|$iSearch|$iPath|$bRec|$sExclude|$iRet", 10, 15, 780, 90) _GUICtrlListView_SetColumnWidth ($ListView, 0, 295) _GUICtrlListView_SetColumnWidth ($ListView, 1, 120) _GUICtrlListView_SetColumnWidth ($ListView, 2, 60) _GUICtrlListView_SetColumnWidth ($ListView, 3, 60) _GUICtrlListView_SetColumnWidth ($ListView, 4, 60) _GUICtrlListView_SetColumnWidth ($ListView, 5, 120) _GUICtrlListView_SetColumnWidth ($ListView, 6, 60) GUISetState () ; DISPLAY PARMS IN --------------------------------------------------------------------- GuiCtrlCreateListViewItem($sPath & "|" & $sFilter & "|" & $iSearchType & "|" & $iPathType & "|" & $bRecursive & "|" & $sExclude & "|" & $iRetFormat, $ListView) ; store original parms ---------------------------------------------------------- $save_sPath = $sPath $save_sFilter = $sFilter $save_iSearchType = $iSearchType $save_iPathType = $iPathType $save_bRecursiv = $bRecursive $save_sExclude = $sExclude $save_iRetFormat = $iRetFormat ; old parameters edits ----------------------------------------------- $t1 = TimerInit() For $x = 1 to 1000 If $sPath = -1 Or $sPath = Default Then $sPath = @ScriptDir If $sFilter = -1 Or $sFilter = Default Then $sFilter = "*" If $iSearchType = -1 Or $iSearchType = Default Then $iSearchType = 0 If $iPathType = -1 Or $iPathType = Default Then $iPathType = 0 If $bRecursive = Default Then $bRecursive = False If $sExclude = -1 Or $sExclude = Default Then $sExclude = "" If $iRetFormat = -1 Or $iRetFormat = Default Then $iRetFormat = 1 Next $t1 = TimerDiff($t1) GuiCtrlCreateListViewItem($sPath & "|" & $sFilter & "|" & $iSearchType & "|" & $iPathType & "|" & $bRecursive & "|" & $sExclude & "|" & $iRetFormat, $ListView) ; restore original parms ------------------------------------------------------- $sPath = $save_sPath $sFilter = $save_sFilter $iSearchType = $save_iSearchType $iPathType = $save_iPathType $bRecursive = $save_bRecursiv $sExclude = $save_sExclude $iRetFormat = $save_iRetFormat ; new parameter edits ------------------------------------------------ $t2 = TimerInit() For $x = 1 to 1000 If $sPath = -1 Or $sPath = Default Or $sPath == "" Then $sPath = @ScriptDir If $sFilter = -1 Or $sFilter = Default Or $sFilter == "" Then $sFilter = "*" If Not ($iSearchType == "1") And Not ($iSearchType == "2") Then $iSearchType = "0" If Not ($iPathType == "1") And Not ($iPathType == "2") Then $iPathType = "0" If $bRecursive = "1" Then $bRecursive = True Else $bRecursive = False EndIf If $sExclude = -1 Or $sExclude = Default Then $sExclude = "" If Not ($iRetFormat == "0") And Not ($iRetFormat == "2") Then $iRetFormat = "1" Next $t2 = TimerDiff($t2) GuiCtrlCreateListViewItem($sPath & "|" & $sFilter & "|" & $iSearchType & "|" & $iPathType & "|" & $bRecursive & "|" & $sExclude & "|" & $iRetFormat, $ListView) ;------------------------------------------------------------------------------- While 1 If GUIGetMsg() = -3 Then ExitLoop WEnd GUIDelete() EndFunc 2. If a user were to call this function with values in our 2 "do not use" internal parameters, the results are unpredictable. This is not uncommon in production UDF functions. So, we might as well cut the number of internal parms down to one. Completely removing $bRunFirstTime, and setting the Func default for $sTWorkPath to something like "/*firstcall*/" (a value that will never be passed internally) should do the trick. Then replace the "If $bRunFirstTime Then" statement with: If $sWorkPath= "/*firstcall*/" Then $sWorkPath = "" 3. (I'm nitpicking now) We haven't really abbreviated our other variable names, could we globally change $bRecursiv to $bRecursive ? 4. (Still nitpicking) Would KaFu and Ascend4nt mind if the "Thanks" comment were pulled off the one SRE statement? A *LOT* of people have contributed to this function past and present, and we'd have a list 30-names long to name them all. I don't see those types of comments too often in production. Edit: These changes will, of course, result in: _FileListToArraySuperTurbo4000PlusProWithMoreUltraPowerboost Edited July 3, 2009 by Spiff59 Link to comment Share on other sites More sharing options...
Tlem Posted July 3, 2009 Author Share Posted July 3, 2009 What a road crossed since the first one post!!! Very very beautiful work of BaKaMu and Spiff59 and which magnificent function. I go away this evening 10 days in vacancy (without pc), thus when I would return, I would doubtless see still improvements of your part... Once again thanks to both. Best Regards.Thierry Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now