Jump to content
bobmcrae

Slow UDF Performance

Recommended Posts

bobmcrae

I have a very simple UDF, which contains a few "helper" functions, like the one below (_getNetworkDrive).  I notice that when I call this function from my main script, which is approaching 3000-lines of code (big & some what complex), the performance of the UDF function _getNetworkDrive is very slow as compared to when I call the same function from a simple test script.  I do not have any different processing happening (e.g., launching another script) between the BIG script and the small test script.  I also confirmed that the CPU & memory are nominal (not significantly different from the test script) when the BIG script is running the _getNetworkDrive function.

To quantify the performance hit, I ran several times with the test script and see that the function takes about 30-mSec, with a few peaks near 300-mSec.  The same function/UDF called from the BIG script takes anywhere from 1-second (on the low end) to as much as 16-seconds!  So, we're talking about 2-3 orders of magnitude difference.  The majority of processing time seems to be in the For/Next loop that is iterating through the drives.  I suspect that the culprit is the FileExists($drive) conditional check, but I cannot understand why that would be the case when called from a larger script.

Any ideas of why the UDF function's performance would suffer  when part of a larger script?

 

zc?&R6?73?&?46?FR&WGG?&??B??r?WF??B#?ФgV?2?vWD?WGv?&?G&?fR??Р???FW&FRF?&?Vv?F?R?WGv?&?G&?fW0Р?FG&?fTFWF??2?b33???LJ???'&?6?gG?6??54??Feuuu&??Bb33??Р?FG&?fW2?G&?fTvWDG&?fR?b33???WGv?&?b33???Р??bT&?V?B?FG&?fW2?fwC??"F?V?Р??f?"F??F?FG&?fW5??Р???FG&?fR?FG&?fW5?F??Р????b7G&??t??7G"?G&?fT?vWB?FG&?fR??FG&?fTFWF??2??Bf??TW??7G2?FG&?fR?F?V?Р????&WGW&?FG&?fPР???V?D?`Р???W?@Р?V?D?`РР????G&?fRf?V?B?GFV?BF??Р?FG&?fR?G&?fT?FB?b33???b33???FG&?fTFWF??2??G6gG7W6W"?G6gG772?Р??b??BFG&?fRF?V?&WGW&?6WDW'&?"????b33???WGv?&?G&?fR?b33??f??FG&?fTFWF??2f??b33???6?V?B??B&R?VBb33???РФV?DgV?2??vWD?WGv?&?G&?fR????&S???

 

Share this post


Link to post
Share on other sites
Jos

Not sure what the last couple of line are, or should that be the UDF you are referring to?
I can't imagine why there would be a significant difference either between a large and small script using the same UDF.
Maybe you can insert some consolewrite statements showing the actual time it takes in the different scenario's.

Jos


Visit the SciTE4AutoIt3 Download page for the latest versions  - Beta files                                How to post scriptsource        Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites
water

Can you at least post the _getNetworkDrive function (maybe it's the unreadable lines at the end of your post)?
Maybe your code runs into some kind of timeout when checking for a non existing network drive?


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
bobmcrae

How weird, I posted the code in the original posting using the <> (code) tool.  I'll try again here.

Jos, the times I was reporting were from a consolewrite of TimerInit & TimerDiff portions built into the function.  Hopefully, you can see that below.

Func _getNetworkDrive()
$t1 = TimerInit()
    ; Iterate through the network drives
    $driveDetails = '\\xxx.brickftp.com@SSL\DavWWWRoot'
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $driveDetails = ' & $driveDetails & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $drives = DriveGetDrive('Network')
    If UBound($drives)>=2 Then
        For $i=1 To $drives[0]
            $drive = $drives[$i]
            ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $drive = ' & $drive & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
            If StringInStr(DriveMapGet($drive), $driveDetails) And FileExists($drive) Then
                ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : TimerDiff($t1) = ' & TimerDiff($t1) & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
                Return $drive
            EndIf
        Next
    EndIf

    ; No drive found, attempt to map
    $drive = DriveMapAdd('*', $driveDetails, 1,  $sftpCpUser, $sftpCpPass)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : TimerDiff($t1) = ' & TimerDiff($t1) & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    If Not $drive Then Return SetError(-1, 0, 'Network drive (' & $driveDetails & ') could not be mapped')

EndFunc ; _getNetworkDrive()

 

Share this post


Link to post
Share on other sites
bobmcrae

Well, I guess I just needed to "verbalize" the problem...I traced the issue to another UDF include (VirtualFlex.Memory.au3 by @prazetto), which apparently is causing the SIGNIFICANT slow-down.  I only use this UDF in one place and could probably do without.  So, in the absence of time to investigate, I am going to remove that dependency.  In doing so, the BIG script now returns the _getNetworkDrive function in a few milliseconds.  I suspect the VirtualFlex.Memory.au3 UDF virtualization causes the slow-down maybe @prazetto could investigate the issue?

 

Edited by bobmcrae
spelling

Share this post


Link to post
Share on other sites

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

  • Similar Content

    • ScriptJunky
      By ScriptJunky
      I noticed a lack of a constants file for _WinAPI_GetSystemMetrics() so I made this for anyone who wants to add it to their library. Enjoy!  (file attached below)
      #include-once ; #INDEX# ======================================================================================================================= ; Title .........: WinAPI GetSystemMetrics Constants ; AutoIt Version : 3.3.14.5 ; Language ......: English ; Description ...: Constants for _WinAPI_GetSystemMetrics(). ; Author(s) .....: ScriptJunky ; =============================================================================================================================== ; #CONSTANTS# =================================================================================================================== ; _WinAPI_GetSystemMetrics() Global Const $ARRANGE = 56 Global Const $CLEANBOOT = 67 Global Const $CMONITORS = 80 Global Const $CMOUSEBUTTONS = 43 Global Const $CONVERTIBLESLATEMODE = 0x2003 Global Const $CXBORDER = 5 Global Const $CXCURSOR = 13 Global Const $CXDLGFRAME = 7 Global Const $CXDOUBLECLK = 36 Global Const $CXDRAG = 68 Global Const $CXEDGE = 45 Global Const $CXFIXEDFRAME = 7 Global Const $CXFOCUSBORDER = 83 Global Const $CXFRAME = 32 Global Const $CXFULLSCREEN = 16 Global Const $CXHSCROLL = 21 Global Const $CXHTHUMB = 10 Global Const $CXICON = 11 Global Const $CXICONSPACING = 38 Global Const $CXMAXIMIZED = 61 Global Const $CXMAXTRACK = 59 Global Const $CXMENUCHECK = 71 Global Const $CXMENUSIZE = 54 Global Const $CXMIN = 28 Global Const $CXMINIMIZED = 57 Global Const $CXMINSPACING = 47 Global Const $CXMINTRACK = 34 Global Const $CXPADDEDBORDER = 92 Global Const $CXSCREEN = 0 Global Const $CXSIZE = 30 Global Const $CXSIZEFRAME = 32 Global Const $CXSMICON = 49 Global Const $CXSMSIZE = 52 Global Const $CXVIRTUALSCREEN = 78 Global Const $CXVSCROLL = 2 Global Const $CYBORDER = 6 Global Const $CYCAPTION = 4 Global Const $CYCURSOR = 14 Global Const $CYDLGFRAME = 8 Global Const $CYDOUBLECLK = 37 Global Const $CYDRAG = 69 Global Const $CYEDGE = 46 Global Const $CYFIXEDFRAME = 8 Global Const $CYFOCUSBORDER = 84 Global Const $CYFRAME = 33 Global Const $CYFULLSCREEN = 17 Global Const $CYHSCROLL = 3 Global Const $CYICON = 12 Global Const $CYICONSPACING = 39 Global Const $CYKANJIWINDOW = 18 Global Const $CYMAXIMIZED = 62 Global Const $CYMAXTRACK = 60 Global Const $CYMENU = 15 Global Const $CYMENUCHECK = 72 Global Const $CYMENUSIZE = 55 Global Const $CYMIN = 29 Global Const $CYMINIMIZED = 58 Global Const $CYMINSPACING = 48 Global Const $CYMINTRACK = 35 Global Const $CYSCREEN = 1 Global Const $CYSIZE = 31 Global Const $CYSIZEFRAME = 33 Global Const $CYSMCAPTION = 51 Global Const $CYSMICON = 50 Global Const $CYSMSIZE = 53 Global Const $CYVIRTUALSCREEN = 79 Global Const $CYVSCROLL = 20 Global Const $CYVTHUMB = 9 Global Const $DBCSENABLED = 42 Global Const $DEBUG = 22 Global Const $DIGITIZER = 94 Global Const $IMMENABLED = 82 Global Const $MAXIMUMTOUCHES = 95 Global Const $MEDIACENTER = 87 Global Const $MENUDROPALIGNMENT = 40 Global Const $MIDEASTENABLED = 74 Global Const $MOUSEPRESENT = 19 Global Const $MOUSEHORIZONTALWHEELPRESENT = 91 Global Const $MOUSEWHEELPRESENT = 75 Global Const $NETWORK = 63 Global Const $PENWINDOWS = 41 Global Const $REMOTECONTROL = 0x2001 Global Const $REMOTESESSION = 0x1000 Global Const $SAMEDISPLAYFORMAT = 81 Global Const $SECURE = 44 Global Const $SERVERR = 289 Global Const $SHOWSOUNDS = 70 Global Const $SHUTTINGDOWN = 0x2000 Global Const $SLOWMACHINE = 73 Global Const $STARTER = 88 Global Const $SWAPBUTTON = 23 Global Const $TABLETPC = 86 Global Const $XVIRTUALSCREEN = 76 Global Const $YVIRTUALSCREEN = 77  
      WinAPISystemMetricsConstants.au3
    • rcmaehl
      By rcmaehl
      A UDF with Extended Functions for Window Management
       
      Notes:
      Fixes WinGetClassList's barbaric returning of a @LF separated string instead of an array.
       
      Potential Uses:
      Automating applications that change their controls' handles/classes on each launch (e.g. half of Cisco's programs)
       
      Functions:
      _WinGetClassList
      _WinGetClassNNList
      _WindowGetHandleList
      _WindowGetHandleListFromPos
       
      Download: 
      WindowEx.zip  (v0.4)
       
      Changelog:
      10/04/2016 (v0.4): _WinGetClassNNList Fixed : Not Returning an Index when using $2D_ARRAY _WinGetClassNNList Fixed : Not Properly returning $aArray[x][1] on Classes with instances > 9 when using $2D_ARRAY 10/03/2016 (v0.3): _WinGetClassList Added : Exactly the same as WinGetClassList but returns a more civilized Array _WinGetClassNNList Added : Returns Classes and their instances in either a 1D or 2D array depending on Flags _WindowGetHandleList Renamed: _WinGetHandleList SCRIPT BREAKING! _WindowGetHandleListFromPos Renamed: _WinGetHandleListFromPos SCRIPT BREAKING! 10/01/2016 (v0.2): WindowsExConstants.au3 Added : Flags in _WindowGetHandleListFromPos _WindowGetHandleListFromPos Removed: ConsoleWrite left in during debug _WindowGetHandleListFromPos Added : Flag for if part of a Control is at $X, $Y return it as well. 10/01/2016 (v0.1): _WindowGetHandleList Added : Retrieves the handles of classes from a window. _WindowGetHandleListFromPos Added : Retrieves the handles of classes at a specific position from a window. Known and Reported Bugs:
      None reported To Do:
      To Be Decided. Opinions welcome! Upcoming Changes:
      To Be Decided.
    • FrancescoDiMuro
      By FrancescoDiMuro
      Good morning everyone

      I was playing a little bit with "Screen Capture" UDF, and I was trying to make a "Window" capture, but, since I made a GUI which through I fire the event "Capture", my GUI is captured as well, and I don't want to
      This is the line of code that makes the capture:
       
      _ScreenCapture_CaptureWnd($strScreenCaptureFileName, $objActiveWindow, 0, 0, -1, -1, False) And these are the lines of code which select the "active" window:
       
      Local $objCurrentWindow = 9999 If _IsPressed("01") Then $objCurrentWindow = WinGetHandle("[ACTIVE]") If $objCurrentWindow <> $objMyGUI Then $objActiveWindow = $objCurrentWindow EndIf EndIf Sorry If I made stupid mistakes
      Thanks in advance.

      Francesco
    • kcvinu
      By kcvinu
      Hi all,
      I am playing with _GUICtrlButton_Create function. How can i change this button's (or the entire form's) font ?. The in-built GUICtrlSetFont function is not working even when i convert the control handle to control ID with _WinAPI_GetDlgCtrlID ( ) function.  Do i need to use CreateFont api finction and send WM_SETFONT message ? Or is there any other easy and safe ways to do this ?. Thanks in advance.
      Note : This window is created by CreateWindowEx function, not by GUICreate function. 
    • okolaris
      By okolaris
      Hey everyone,
      I thought I might share my little Language UDF plus the more powerful SciTE Tool to ship Strings from SciTE into the xml file. While I haven't had the time to fully adapt the small UDF to one of the big XML-UDFs the so called "Language Transmitter" that basically writes the XML file for you runs mostly on "XML DOM wrapper (COM)" by eltorro. The Transmitter should work with other XML-Language-UDFs depending on their encoding.
       
      First let's start with the UDF, there are two functions of interest: _LangInit($sFilePath) and s($sString) As you will have guessed, _LangInit($sFilePath) is called once to initialize the UDF and s($sString) is used to receive the string to your key. Plain and simple.
      Now to the actual "new" part, the Language Transmitter. It basically allows you to transfer a selected String from SciTE into a xml file. While doing so it will scan for AutoIt variables, macros etc. and parse the string to fit StringFormat(). It then saves the formatted string in the xml file and returns the formatted call into SciTE. If the selected string is already defined it will directly parse the key into SciTE. To change the default output file, you can either edit the ini-file in the @ScriptDir of the LanguageTransmitter.exe or press Alt+A on empty space again and keep clicking cancel/no until the Transmitter let's you select the current output file. Standard output is strings.xml in the current opened AutoIt Script.
      Example:
      ; given the line: MsgBox(16, 'Error', 'Error message') ; select 'Error' run the Transmitter follow the instructions, repeat with 'Error message'. Outcome (e.g.): MsgBox(16, s('Error'), s('Error_msg')) ; Variables and Macro example: $sString = "Value: " & $iValue & @CRLF & 'Another value: '& $iValue2 ; Select the full string including all AutoIt variables and macros etc. in SciTE and press Alt+A (default) to run the LanguageTransmitter ; follow the instructions and it will then paste a formatted string like that into SciTE: $sVar = StringFormat(s('Key'), $iValue, $iValue2) ; the correlating xml entry should look like that: ; <string name="Key">Value: %s\r\nAnother value: %s</string> ; as you can see @CRLF has been replaced with \r\n as well. If you are working on a project and want to directly add a string to the xml file just start the Language Transmitter without selecting any text, enter your string and a key.
      SetUp/Installation
      Examples
      Since xml files are required all examples can be found in the zip file. There are two examples, one includes a language selection interface.
      Language File Checker
      I added a script to check whether the xml file contains all required strings or even unnecessary strings.
       
      Hope you like my little helper!
       
      UDF - LanguageSupport.zip
×