12321 Posted June 12, 2012 Share Posted June 12, 2012 Dear all, I am new to AutoIt and I am confused why my script has such high CPU usage. The script only checks the title of the active window and then waits until that window is not active anymore. Then it checks the title of the new active window and so on and so on.... I included Debug.au3. And it tells me that the script is atm at the WinWaitNotActive($wintitle) but it has a CPU usage of average of 5%. #region options Opt("MustDeclareVars", 1) AutoItSetOption("TrayIconDebug", 1) #endregion options #region include #include<File.au3> #include<Array.au3> #include<Debug.au3> #include<Process.au3> #include<WindowsConstants.au3> #include<GUIConstantsEx.au3> #include<EditConstants.au3> _DebugSetup("debug", 1) #endregion include #region variables Global $wintitle #endregion variables #region loop While 1 ; ### loop ### _DebugOut("StartOfLoop") $wintitle = WinGetTitle("[ACTIVE]") ;title from active window If $wintitle Then ;check that $wintitle is not empty. Else sleep(250). _DebugOut("BeforeWinWaitActive") WinWaitNotActive($wintitle) _DebugOut("AfterWinWaitActive") Else Sleep(250) EndIf _DebugOut("EndOfLoop") WEnd #endregion loop Link to comment Share on other sites More sharing options...
water Posted June 12, 2012 Share Posted June 12, 2012 Why do you wait for the window to become inactive in a loop? You just wait in the loop (no other statements) so you could replace the loop with a single WinWaitNotActive: $wintitle = WinGetTitle("[ACTIVE]") ;title from active window WinWaitNotActive($wintitle) My UDFs and Tutorials: Spoiler UDFs:Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - WikiExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example ScriptsOutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - WikiOutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - DownloadOutlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - WikiPowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - WikiTask Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs:Excel - Example Scripts - WikiWord - Wiki Tutorials:ADO - WikiWebDriver - Wiki Link to comment Share on other sites More sharing options...
12321 Posted June 12, 2012 Author Share Posted June 12, 2012 (edited) Well I just tried it with that test script and realized that I still had the same problem with the high CPU usage like in my "real" script. My real script is longer, so I just posted the test script. Below you can find my "real" script. To run this script 4 files are necessary: listsWhitelistTitle listsWhitelistProcess listsBlacklistProcess listsBlacklistTitle But I observe the high CPU usage in both scripts. expandcollapse popup#region options Opt("MustDeclareVars", 1) AutoItSetOption("TrayIconDebug", 1) AutoItSetOption("TrayAutoPause", 0) ;~ AutoItSetOption("TrayIconHide",1) #endregion options #region include #include<File.au3> #include<Array.au3> #include<Debug.au3> #include<Process.au3> #include<WindowsConstants.au3> #include<GUIConstantsEx.au3> #include<EditConstants.au3> _DebugSetup("debug procrastination", 1) #endregion include #region variables Global $aWhitelistTitle Global $aWhitelistProcess Global $aBlacklistProcess Global $aBlacklistTitle Global $hGUI Global $input_process Global $input_title Global $button_whitelist_process Global $button_whitelist_title Global $button_blacklist_process Global $button_blacklist_title Global $GUImsg Global $learn_new #endregion variables #region load lists ; whitelist_title to array Global $sFile1 = @ScriptDir & "listsWhitelistTitle" ;WhitelistTitle file one entry per line _FileReadToArray($sFile1, $aWhitelistTitle) If @error = 1 Then MsgBox(4096, "Error", "Error opening file: WhitelistTitle") Exit ElseIf @error = 2 Then MsgBox(4096, "Error", "Corrupted file: WhitelistTitle") Exit EndIf _DebugOut("Whitelist_title2Array_Successful") Sleep(100) ; whitelist_title to array Global $sFile2 = @ScriptDir & "listsWhitelistProcess" ;WhitelistProcess file one entry per line _FileReadToArray($sFile2, $aWhitelistProcess) If @error = 1 Then MsgBox(4096, "Error", "Error opening file: WhitelistProcess") Exit ElseIf @error = 2 Then MsgBox(4096, "Error", "Corrupted file: WhitelistProcess") Exit EndIf _DebugOut("Whitelist_process2Array_Successful") Sleep(100) ; blacklist process to array Global $sFile3 = @ScriptDir & "listsBlacklistProcess" ;BlacklistProcess file one entry per line _FileReadToArray($sFile3, $aBlacklistProcess) If @error = 1 Then MsgBox(4096, "Error", "Error opening file: BlacklistProcess") Exit ElseIf @error = 2 Then MsgBox(4096, "Error", "Corrupted file: BlacklistProcess") Exit EndIf _DebugOut("Blacklist_process2Array_Successful") ; blacklist title to array Global $sFile4 = @ScriptDir & "listsBlacklistTitle" ;BlacklistTitle file one entry per line _FileReadToArray($sFile4, $aBlacklistTitle) If @error = 1 Then MsgBox(4096, "Error", "Error opening file: BlacklistTitle") Exit ElseIf @error = 2 Then MsgBox(4096, "Error", "Corrupted file: BlacklistTitle") Exit EndIf _DebugOut("Blacklist_title2Array_Successful") Sleep(100) #endregion load lists #region loop $learn_new = 1 ; variable that checks if a process or title is already in the arrray While 1 ; ### loop ### _DebugOut("StartOfLoop") Global $wintitle = WinGetTitle("[ACTIVE]") ;title from active window If $wintitle Then ;check that $wintitle is not empty. Else sleep(250). Global $winprocess = _ProcessGetName(WinGetProcess($wintitle)) ;process name from active window For $i = 1 To $aWhitelistProcess[0] ;checks if the process name is on the whitelist Sleep(50) If $winprocess = $aWhitelistProcess[$i] Then _DebugOut("Whitelist_process_BeforePause") WinWaitNotActive($wintitle) ;if process name is on whitelist script pauses until other window is active. _DebugOut("Whitelist_process_AfterPause") $learn_new = 0 ; if process name is on whitelist no need to learn new process name EndIf Next Sleep(50) If $learn_new Then ;only check other lists if process is not in whitelist_process (hence if the For loop haven't set the $learn_new variable to 0). For $i = 1 To $aBlacklistProcess[0] ;checks if the process name is on the blacklist If $winprocess = $aBlacklistProcess[$i] Then ProcessClose($winprocess) ;close process if on blacklist $learn_new = 0 ;if name on list no need to learn new process name _DebugOut("processclose") EndIf Next Sleep(50) If $learn_new Then ;only check other lists if process is not in whitelistprocess AND blacklistprocess For $i = 1 To $aBlacklistTitle[0] ;checks if the window title is on the blacklist If StringInStr($wintitle, $aBlacklistTitle[$i]) Then WinSetState($wintitle, "", @SW_HIDE) ;hide window if on blacklist $learn_new = 0 ;if name on list no need to learn new process name _DebugOut("winclose") EndIf Next Sleep(50) If $learn_new Then ;only check list if process is not in whitelistprocess AND blacklistprocess OR title is not in blacklist For $i = 1 To $aWhitelistTitle[0] ;checks if the window title is on the whitelist If StringInStr($wintitle, $aWhitelistTitle[$i]) Then _DebugOut("Whitelist_title_BeforePause") WinWaitNotActive($wintitle) ;if process name is on whitelist script pauses until other window is active. _DebugOut("Whitelist_title_AfterPause") $learn_new = 0 ;if name on list no need to learn new process name EndIf Next Sleep(50) EndIf EndIf EndIf _learnnew() _learnnewgetmsg() Sleep(50) $learn_new = 1 Else Sleep(250) EndIf _DebugOut("EndOfLoop") WEnd #endregion loop #region functions Func _learnnew() ;create GUI if new programm If $learn_new Then $hGUI = GUICreate("Learning mode - Procrastination Killer", 425, 85, -1, -1, -1, $WS_EX_TOPMOST) $input_process = GUICtrlCreateInput($winprocess, 5, 5, 415, 20, BitOR($ES_CENTER, $ES_READONLY)) $input_title = GUICtrlCreateInput($wintitle, 5, 30, 415, 20, $ES_CENTER) $button_whitelist_process = GUICtrlCreateButton("Whitelist Process", 5, 55, 100, 25) $button_whitelist_title = GUICtrlCreateButton("Whitelist Title", 110, 55, 100, 25) $button_blacklist_process = GUICtrlCreateButton("Blacklist Process", 215, 55, 100, 25) $button_blacklist_title = GUICtrlCreateButton("Blacklist Title", 320, 55, 100, 25) GUISetState(@SW_SHOW) EndIf EndFunc ;==>_learnnew Func _learnnewgetmsg() ;while GUI active GUIGetMsg While WinGetHandle("[ACTIVE]") = $hGUI $GUImsg = GUIGetMsg() Select Case $GUImsg = $button_whitelist_title _ArrayAdd($aWhitelistTitle, GUICtrlRead($input_title)) _DebugOut("#whitelisttitle " & $aWhitelistTitle[0]) $aWhitelistTitle[0] += 1 _DebugOut("#whitelisttitle " & $aWhitelistTitle[0]) Global $hFile1 = FileOpen($sFile1, 2) _FileWriteFromArray($hFile1, $aWhitelistTitle, 1) FileClose($hFile1) GUIDelete($hGUI) Case $GUImsg = $button_whitelist_process _ArrayAdd($aWhitelistProcess, GUICtrlRead($input_process)) _DebugOut("#whitelistprocess " & $aWhitelistProcess[0]) $aWhitelistProcess[0] += 1 _DebugOut("#whitelistprocess " & $aWhitelistProcess[0]) Global $hFile2 = FileOpen($sFile2, 2) _FileWriteFromArray($hFile2, $aWhitelistProcess, 1) FileClose($hFile2) GUIDelete($hGUI) Case $GUImsg = $button_blacklist_process _ArrayAdd($aBlacklistProcess, GUICtrlRead($input_process)) _DebugOut("#blacklistprocess " & $aBlacklistProcess[0]) $aBlacklistProcess[0] += 1 _DebugOut("#blacklistprocess " & $aBlacklistProcess[0]) Global $hFile3 = FileOpen($sFile3, 2) _FileWriteFromArray($hFile3, $aBlacklistProcess, 1) FileClose($hFile3) GUIDelete($hGUI) Case $GUImsg = $button_blacklist_title _ArrayAdd($aBlacklistTitle, GUICtrlRead($input_title)) _DebugOut("#blacklisttitle " & $aBlacklistTitle[0]) $aBlacklistTitle[0] += 1 _DebugOut("#blacklisttitle " & $aBlacklistTitle[0]) Global $hFile4 = FileOpen($sFile4, 2) _FileWriteFromArray($hFile4, $aBlacklistTitle, 1) FileClose($hFile4) GUIDelete($hGUI) EndSelect WEnd EndFunc ;==>_learnnewgetmsg #endregion functions Edited June 12, 2012 by 12321 Link to comment Share on other sites More sharing options...
Decipher Posted June 12, 2012 Share Posted June 12, 2012 (edited) I don't know if this will help or not but it is a different method. Global $sWindowActive = False Global $sWindow = "Window Title" ; or Handle AdlibRegister("_IsWindowActive", 1000) ; Second parameter is interval in miliseconds to execute function. ; Your Main Loop If $sWindowActive Then ; Do something here $sWindowActive = False ; Set global variable back to false. EndIf While 1 Sleep(5000) ; This will not interupt the execution of the registered function. WEnd Func _IsWindowActive() If WinActive($sWindow) Then $sWindowActive = True EndIf Edited June 12, 2012 by Decipher Spoiler Link to comment Share on other sites More sharing options...
12321 Posted June 12, 2012 Author Share Posted June 12, 2012 Wow! I just came back home and turn on my computer again. I was about to check the solution of Decipher. But first I ran the test script and my average CPU usage was slightly above zero when the script was at WinWaitNotActive. Then I tried the "real" script and the same result slightly above zero !!! I have no clue what caused the high CPU usage of the both scripts, but without any change it's fine now! btw I ran another script when I observed the high CPU usage and that didn't cause a high CPU usage... Weired... but thanks for the replys and AdlibRegister I might use for the GUIGetMsg() while the loop is running. Link to comment Share on other sites More sharing options...
12321 Posted July 16, 2012 Author Share Posted July 16, 2012 Okay I was to quick with my reply. Today I was working on that script again and I observed a rather high CPU usage again. Maybe someone else can test it too? Here two basic scripts to compare. Using the first one I have continuously a CPU usage of ~5%. But using the second one I have a CPU usage of ~0%. While 1 Local $wintitle = WinGetTitle("[ACTIVE]") ;title from active window If $wintitle Then ;check that $wintitle is not empty. Else sleep(250). WinWaitNotActive($wintitle) Else Sleep(250) EndIf WEnd While 1 Local $wintitle = WinGetTitle("[ACTIVE]") ;title from active window If $wintitle Then ;check that $wintitle is not empty. Else sleep(250). Sleep(250) Else Sleep(250) EndIf WEnd Why this difference? I don't know. Well I use in my script now Sleep(250) instead of WinWaitNotActive($wintitle)... Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted July 16, 2012 Moderators Share Posted July 16, 2012 12321, Why this difference? I don't knowWhy are you surprised at the difference? In the first snippet you are never giving the CPU a chance to take a breather if there is an active window (which there probably will be): Start the loop: WinGetTitle If we have a title Then Run round the loop again with no pause Else Give the CPU a rest EndIf See what I mean? In your second snippet you Sleep regardless of the condition - so you might as well put it outside the If structure and pause on every pass. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
12321 Posted July 16, 2012 Author Share Posted July 16, 2012 (edited) Why are you surprised at the difference? In the first snippet you are never giving the CPU a chance to take a breather if there is an active window...See what I mean? Actually I do not see what you mean The AutoIt help tells me "The script polls for a window match every 250 milliseconds or so."So I thought that the CPU has 250ms time to take a breather. Did I misunderstood it?BTW yes I know that the second script is nonsense... Just changed one line, was enough to test the CPU usage Edited July 16, 2012 by 12321 Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted July 16, 2012 Moderators Share Posted July 16, 2012 12321, You are quite right - my apologies. I completely misread the script. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
12321 Posted July 17, 2012 Author Share Posted July 17, 2012 I am new to AutoIt and programming and so on so I don't know But isn't the fact that WinWaitNotActive is not "sleeping" 250ms like described in the help file enough for a bug report? BTW someone compared the high CPU usage of the 2 scripts on their computer (see ) ??? Link to comment Share on other sites More sharing options...
lark Posted July 17, 2012 Share Posted July 17, 2012 It might be a problem with WinWaitNotActive, but here is a way to work around it; assuming that you to manually put in the sleep(250) to avoid high CPU usage, you could do something like Local $wintitle While 1 $wintitle = WinGetTitle("[ACTIVE]") If $wintitle Then Do Sleep(250) Until Not WinActive($wintitle) EndIf Sleep(250) WEnd Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted July 17, 2012 Moderators Share Posted July 17, 2012 12321,I do not see the same high CPU usage as you when I run that script - it sits around 0-2% when nothing else is running which is about the norm for AutoIt. But if you want to open a bug report, please do so here. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
12321 Posted July 18, 2012 Author Share Posted July 18, 2012 @Melba23 Okay that's weird that you don't see the high CPU usage.@lark thanks for the idea.All three options should have more or less the same outcome and all "sleep" 250ms, but letting them run I find following CPU usages:1. Using sleep(250) I have a max CPU usage of 1% and an average of ~0%.2. Using WinWaitNotActive($wintitle) a max CPU usage of 10% and an average of ~5%.3. Until Not WinActive($wintitle) has a max CPU usage of 2% and an average of ~0.1%Over and over again same result. Well I cannot explain it, but as long as I found a nice solution [just a simple sleep(250)] it is okay 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