Jump to content

_FileFindEx - Get More from File/Folder Searches


Ascend4nt
 Share

Recommended Posts

Okay, was a bit unhappy with the optimizations, so made one more. To take it one step further, one can use the $FFX_ constants and call the internal function __FFEXWT_Convert()..

5/24/2011: Further speed optimization when using _FileFindExTimeConvert().

*Edit: Found out speed is severely affected when run in x64 mode! Therefore I recommend running/compiling this code in x86 (32-bit) mode for best performance!

Edited by Ascend4nt
Link to comment
Share on other sites

I remember threads on the performance variations on If/Then vs. If/Then/EndIf. The thing is, its not a universal truth that the latter is always faster. In fact, for cases where the 'If' statement turns out to be False, its actually faster to have only the If/Then variation when the result is typically false, as it is in parameter-checks and DLLCall error-checks. So in that way, my code is pretty much already optimized.

Run this to see what I mean:

Local $iTimer,$iVar=1

$iTimer=TimerInit()
For $i=1 To 500000
    If $iVar=0 Then $iVar=1
Next
ConsoleWrite("Time to execute:"&TimerDiff($iTimer)&" ms"&@LF)

$iTimer=TimerInit()
For $i=1 To 500000
    If $iVar=0 Then
        $iVar=1
    EndIf
Next
ConsoleWrite("Time to execute:"&TimerDiff($iTimer)&" ms"&@LF)

What gets me is how slow the 64-bit code is. I'm pretty sure it has to do with AutoIt's implementation of DLLCall() being unoptimized...

How many others get the same result (ie the 64-bit slowdown)?

*edit: code example

Edited by Ascend4nt
Link to comment
Share on other sites

Run this to see what I mean:

What confuses me most is that even if you set $iVar = 0 the first option is still faster :alien:;) ...

How many others get the same result (ie the 64-bit slowdown)?

Same here, your function running as 64-bit is much slower (which does not bother me as SMF needs to be compiled to 32bit due to the dlls anyhow :ph34r: ).

Edit:

Exchanging it in SMF took me 20 minutes... and it's definitely faster :), awesome work m8 :huh2: !

Edited by KaFu
Link to comment
Share on other sites

What confuses me most is that even if you set $iVar = 0 the first option is still faster :alien:;) ...

Oh, if you do that, the statement ceases to be true on subsequent passes. The 'Then' part should be changed to '$iVar=0' instead of '$iVar=1'. After that, it'll show you that the 2nd option is faster for True 'If' statements.

Same here, your function running as 64-bit is much slower (which does not bother me as SMF needs to be compiled to 32bit due to the dlls anyhow :ph34r: ).

Edit:

Exchanging it in SMF took me 20 minutes... and it's definitely faster :), awesome work m8 :huh2: !

Great to hear! And thanks for the 64-bit check. That kinda makes me want to test other code in both bit modes for speed comparisons.

Edited by Ascend4nt
Link to comment
Share on other sites

Tested on Windows 7 x64.

When using the x32 Version of AutoIt I found that _FileFindEx() was faster by an average of 150ms. But when run using the x64 Version of AutoIt the difference was huge. _FileFindEx() was again faster but the difference was 900ms between _FileFindEx() & the inbuilt versions!

Nice Function(s)!

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

  • 4 months later...

Hi,

I tested the function on a win xp64 machine both scripts compiled as x86 and The autoit functions are faster :graduated: . What I am doing wrong?

Below the scripts

$OrdersDir = "X:\ES\"
FileDelete($OrdersDir & "oif*.txt")
while 1
$search = FileFindFirstFile($OrdersDir & "oif*.txt")
While $search <> -1
  $file = FileFindNextFile($search)
  If @error Then
   FileClose($search)
   ExitLoop
  EndIf
  $Filesize = FileGetSize($OrdersDir & $file)
  If $Filesize > 0 Then
   _dbg("AutoIt: Order Received")
   $Order = StringSplit(FileRead($OrdersDir & $file), ";")
   FileMove($OrdersDir & $file, $OrdersDir & "Exec\*.txt", 1)
  EndIf
WEnd
sleep(5)
WEnd
Func _dbg($msg = "NotFound")
Global $Pass
$Pass += 1
$Pass = String($Pass)
$PID = String(@AutoItPID)
If $msg = "NotFound" Then
  DllCall("kernel32.dll", "none", "OutputDebugString", "str", $PID & " Pass: " & $Pass)
Else
  DllCall("kernel32.dll", "none", "OutputDebugString", "str", $msg)
EndIf
EndFunc   ;==>_dbg

#include <_FileFindEx.au3>
$OrdersDir = "X:\ES2\"
FileDelete($OrdersDir & "oif*.txt")
while 1
$search = _FileFindExFirstFile($OrdersDir & "oif*.txt")
While $search <> -1
  If $search[3] > 0 Then
   _dbg("AutoIt: EX Order Received")
   $Order = StringSplit(FileRead($OrdersDir & $search[0]), ";")
   FileMove($OrdersDir & $search[0], $OrdersDir & "Exec\*.txt", 1)
  Else
   ExitLoop
  EndIf
  If Not _FileFindExNextFile($search) then
   _FileFindExClose($search)
  ExitLoop
EndIf
WEnd
sleep(5)
WEnd
Func _dbg($msg = "NotFound")
Global $Pass
$Pass += 1
$Pass = String($Pass)
$PID = String(@AutoItPID)
If $msg = "NotFound" Then
  DllCall("kernel32.dll", "none", "OutputDebugString", "str", $PID & " Pass: " & $Pass)
Else
  DllCall("kernel32.dll", "none", "OutputDebugString", "str", $msg)
EndIf
EndFunc   ;==>_dbg

You take the diference of 2 time values to find the time needed each function to see the file and report the size.

#, Time , Process

1 0.00000000 [3284] AutoIt: Order Received

2 0.00055759 [3284] AutoIt: Order Received

3 0.00112891 [3284] AutoIt: Order Received

4 0.00162222 [3284] AutoIt: Order Received

5 0.00253099 [3284] AutoIt: Order Received

6 0.00291112 [3284] AutoIt: Order Received

7 0.00349047 [3284] AutoIt: Order Received

8 0.00385437 [3284] AutoIt: Order Received

9 0.00431364 [3284] AutoIt: Order Received

10 0.00485418 [3284] AutoIt: Order Received

1 0.00000000 [1660] AutoIt: EX Order Received

2 0.47575378 [1660] AutoIt: EX Order Received

3 0.47759247 [1660] AutoIt: EX Order Received

4 0.47883606 [1660] AutoIt: EX Order Received

5 0.47932434 [1660] AutoIt: EX Order Received

6 0.47982025 [1660] AutoIt: EX Order Received

7 0.48047638 [1660] AutoIt: EX Order Received

8 0.48097992 [1660] AutoIt: EX Order Received

9 0.48139954 [1660] AutoIt: EX Order Received

10 0.48213196 [1660] AutoIt: EX Order Received

Edited by mailro
Link to comment
Share on other sites

I tested the function on a win xp64 machine both scripts compiled as x86 and The autoit functions are faster ;) . What I am doing wrong?

I would often question myself - who in their right mind owns Windows XP 64. Now I have my answer :graduated:

As far as _FileFindEx being slower, it depends on how many file attributes you are looking at - and whether or not you are 'physically' touching each file. In your case, you are reading the entire contents of every file, so there's no need for the functions in my UDF. You won't see a speed advantage. Also, no need to read the filesize. Simply do 'FileRead' and check the # of characters returned to see if it's < 1.

Link to comment
Share on other sites

  • 1 month later...

AutoIt wasn't intended to be used the way it is today.. a lot of features were taken out to simplify programming. FindFirst/Next returning a simple filename was probably the most people needed in the early stages. The rest of the information available is discarded by AutoIt, and, while your suggestion to add it in as extended attributes is a good idea, you'll always get shot down if you request something that can be done through other means. Plus, like Valik said in that ticket, speed is not a concern of the developers. Underscoring that fact is the noticeable speed drop in the latest betas with COM objects, something which has been noted by the developers, but is currently being ignored.

Additionally, you won't get much of anything else added or implemented in AutoIt since DLLCall opens up every nook and cranny of the Windows API. The most basic of things you may expect a language to have implemented won't be, precisely because of that ability to do it 'another way'. I would make a point to say however that AutoIt is currently failing - and in a pretty big way - at being true to its roots in Automation. To fix that would mean adding interfaces for IAccessible and IUIAutomation to the language. Of course, now that ObjCreateInterface() is a part of AutoIt, these important automation interfaces will likely go ignored and the burden will be put on the community to fix that part of AutoIt that no longer works. Might as well rename it 'It'...

oh gee, a soapbox has developed at my feet. I'll step off it now, thanks

Link to comment
Share on other sites

  • 1 month later...

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...