psynegy Posted January 10, 2009 Share Posted January 10, 2009 Any ideas on how I could optimise this code? In a loop it seems to add quite a bit of a lag... :\ Func msnwindowlist() $processes = ProcessList("msnmsgr.exe") For $i = 1 To $processes[0][0] $MSNPID = $processes[$i][1] Next $var = WinList() $list = "" For $i = 1 to $var[0][0] If WinGetProcess($var[$i][0]) = $MSNPID AND $var[$i][0] <> "Windows Live Messenger" AND $var[$i][0] <> "" AND IsVisible($var[$i][1]) AND StringRight($var[$i][0], 5) <> "Alert" Then $list = $list & $var[$i][0] & @LF EndIf Next If $list = "" Then Return 0 Else Return $list EndIf EndFunc Link to comment Share on other sites More sharing options...
AgentSmith15 Posted January 10, 2009 Share Posted January 10, 2009 Func msnwindowlist() $processes = ProcessList("msnmsgr.exe") For $i = 1 To $processes[0][0] $MSNPID = $processes[$i][1] Next $var = WinList() $list = "" For $i = 1 to $var[0][0] If WinGetProcess($var[$i][0]) = $MSNPID AND $var[$i][0] <> "Windows Live Messenger" AND $var[$i][0] <> "" AND IsVisible($var[$i][1]) AND StringRight($var[$i][0], 5) <> "Alert" Then $list = $list & $var[$i][0] & @LF EndIf Next If $list = "" Then Return 0 Else Sleep(10) Return $list EndIf EndFunc Does that do anything? I see there isn't a pause so the function is constantly running. There shouldn't be any effect from adding a sleep.. [center][/center] Link to comment Share on other sites More sharing options...
psynegy Posted January 10, 2009 Author Share Posted January 10, 2009 Func msnwindowlist() $processes = ProcessList("msnmsgr.exe") For $i = 1 To $processes[0][0] $MSNPID = $processes[$i][1] Next $var = WinList() $list = "" For $i = 1 to $var[0][0] If WinGetProcess($var[$i][0]) = $MSNPID AND $var[$i][0] <> "Windows Live Messenger" AND $var[$i][0] <> "" AND IsVisible($var[$i][1]) AND StringRight($var[$i][0], 5) <> "Alert" Then $list = $list & $var[$i][0] & @LF EndIf Next If $list = "" Then Return 0 Else Sleep(10) Return $list EndIf EndFunc Does that do anything? I see there isn't a pause so the function is constantly running. There shouldn't be any effect from adding a sleep.. I have done a small fix, I now only run the check after there has been no user input after 1 second, which means the GUI doesn't get bogged down with the script running. I might put the Sleep in too though, so it doesn't eat up CPU. Cheers Link to comment Share on other sites More sharing options...
TurionAltec Posted January 11, 2009 Share Posted January 11, 2009 (edited) ProcessSetPriority ( @AutoitPID, 1) Will set the priority of the script below normal, so it won't steal cpu time from other applications. Is this function being called inside a tight loop in the main function? If so, add a sleep in there. Something like 250ms may be enough. Unless there's reason to believe multiple msnmsgr.exe are running, why not just do ProcessExists("msnmsgr.exe") to get the PID for MSN. Get the value once before the loop, then refer to it by variable Are you looking for Live messenger chat windows? In version 8, they have in the title "Conversation", and the class "IMWindowClass". This might let you reduce the number of windows you have to process, and also fewer logic checks on the window, which should allow the function to finish faster. In the script below I changed the option for title matching, you may be able to bypass that and just do WinList("[CLASS:IMWindowClass]") For WinGetProcess(), refer to it by window handle ($var[$i][1]) instead of title, which might make it quicker Here's some code with these improvements Global $MSNPID=ProcessExists("msnmsgr.exe") Opt("WinTitleMatchMode",2) ;Search substrings of window titles ProcessSetPriority ( @AutoitPID, 1) ;Lower script priority While 1 $list=msnwindowlist() ;Code that cares about the list sleep(250) ;delay only makes msnwindowlist run 4 times a second, which is probably responsive enough WEnd ;End main code area Func msnwindowlist() $var = WinList("[TITLE:Conversation; CLASS:IMWindowClass]") $list = "" For $i = 1 to $var[0][0] If WinGetProcess($var[$i][1]) = $MSNPID AND IsVisible($var[$i][1]) Then $list = $list & $var[$i][0] & @LF EndIf Next If $list = "" Then Return 0 Else Return $list EndIf EndFunc Edited January 11, 2009 by TurionAltec Link to comment Share on other sites More sharing options...
TurionAltec Posted January 11, 2009 Share Posted January 11, 2009 (edited) I did some tests. If you can just match the class, it's by far the fastest. Plus it returns almost 1/100th the results that you get listing all windows, which will drastically speed up the rest of the function. I also process a loop of Wingetprocess, one with the handle, one with the title. As you can see it is drastically faster with the handle rather than title, and processing 4 entries is a lot quicker than 395 expandcollapse popup$timer=TimerInit() $list=WinList("[CLASS:IMWindowClass]") $timer=TimerDiff($timer) ConsoleWrite("Using class: "&$timer &@CRLF) ConsoleWrite("matches: "&$list[0][0]&@CRLF) $timer=TimerInit() $list=WinList() $timer=TimerDiff($timer) ConsoleWrite("Listing all: "&$timer &@CRLF) ConsoleWrite("matches: "&$list[0][0]&@CRLF) $timer=TimerInit() For $i = 1 to $list[0][0] WinGetProcess($list[$i][1]) Next $timer=TimerDiff($timer) ConsoleWrite("hwnd process: "&$timer&@CRLF) $timer=TimerInit() For $i = 1 to $list[0][0] WinGetProcess($list[$i][0]) Next $timer=TimerDiff($timer) ConsoleWrite("title process: "&$timer&@CRLF) Opt("WinTitleMatchMode",2) $timer=TimerInit() $list=WinList("Conversation") $timer=TimerDiff($timer) ConsoleWrite("Using title: "&$timer &@CRLF) ConsoleWrite("matches: "&$list[0][0]&@CRLF) $timer=TimerInit() For $i = 1 to $list[0][0] WinGetProcess($list[$i][1]) Next $timer=TimerDiff($timer) ConsoleWrite("hwnd process: "&$timer&@CRLF) $timer=TimerInit() For $i = 1 to $list[0][0] WinGetProcess($list[$i][0]) Next $timer=TimerDiff($timer) ConsoleWrite("title process: "&$timer&@CRLF) Results: Using class: 0.840609630553604 matches: 4 Listing all: 5.70016580319566 matches: 395 hwnd process: 6.38125795317561 title process: 91.5068814611913 Using title: 2.10278121940079 matches: 4 hwnd process: 0.0466539741782824 title process: 3.90384811477436 edit:Added Wingetprocess EDIT: here's some testing of the whole code: CODE$timer=TimerInit() For $j =1 to 10 $list=msnwindowlist() Next $timer=TimerDiff($timer)/10 ConsoleWrite("Orig function avg loop time "&$timer&@CRLF) ConsoleWrite($list&@CRLF) Global $MSNPID=ProcessExists("msnmsgr.exe") $timer=TimerInit() For $j =1 to 10 $list=msnwindowlist1() Next $timer=TimerDiff($timer)/10 ConsoleWrite("New function avg loop time "&$timer&@CRLF) ConsoleWrite($list&@CRLF) ;End main function Func msnwindowlist() $processes = ProcessList("msnmsgr.exe") For $i = 1 To $processes[0][0] $MSNPID = $processes[$i][1] Next $var = WinList() $list = "" For $i = 1 to $var[0][0] If WinGetProcess($var[$i][0]) = $MSNPID AND $var[$i][0] <> "Windows Live Messenger" AND $var[$i][0] <> "" AND IsVisible($var[$i][1]) AND StringRight($var[$i][0], 5) <> "Alert" Then $list = $list & $var[$i][0] & @LF EndIf Next If $list = "" Then Return 0 Else Return $list EndIf EndFunc Func IsVisible($handle) If BitAnd( WinGetState($handle), 2 ) Then Return 1 Else Return 0 EndIf EndFunc Func msnwindowlist1() $var = WinList("[CLASS:IMWindowClass]") $list = "" For $i = 1 to $var[0][0] If WinGetProcess($var[$i][1]) = $MSNPID AND IsVisible($var[$i][1]) Then $list = $list & $var[$i][0] & @LF EndIf Next If $list = "" Then Return 0 Else Return $list EndIf EndFunc Orig function avg loop time 105.975982981077 Rick - Conversation Jeff - Conversation John - Conversation Andrew - Conversation New function avg loop time 2.91564989405078 Rick - Conversation Jeff - Conversation John - Conversation Andrew - Conversation Edited January 11, 2009 by TurionAltec Link to comment Share on other sites More sharing options...
Valuater Posted January 11, 2009 Share Posted January 11, 2009 The only problem with the above code having a large sleep is you need to use "OnEventMode" because GUIGetMsg() will not work well at all. another approach... Adlib() Opt("WinTitleMatchMode",2) ;Search substrings of window titles Global $MSNPID=ProcessExists("msnmsgr.exe") ProcessSetPriority ( @AutoitPID, 1) ;Lower script priority AdlibEnable("msnwindowlist", 500) ; this will handle the checking While 1 ;Code that cares about the list WEnd Func msnwindowlist() Local $list = "", $var = WinList("[TITLE:Conversation; CLASS:IMWindowClass]") For $i = 1 to $var[0][0] If WinGetProcess($var[$i][1]) = $MSNPID AND IsVisible($var[$i][1]) Then $list = $list & $var[$i][0] & @LF EndIf Next If $list = "" Then Return 0 Return $list EndFunc 8) Link to comment Share on other sites More sharing options...
Valuater Posted January 11, 2009 Share Posted January 11, 2009 I see all of your edits and additions Turion, I just hope the OP does 8) 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