# Optimisation

## Recommended Posts

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```

##### Share on other sites

```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..

##### Share on other sites

```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

##### Share on other sites

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 by TurionAltec

##### Share on other sites

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

```\$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: 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 by TurionAltec

##### Share on other sites

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.

```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)

##### Share on other sites

I see all of your edits and additions Turion, I just hope the OP does

8)

## Create an account

Register a new account