Hello Community.
as I'm kind of memory usage paranoid.
because i'd like to hear that my app is using less memory from users of my scripts (usually i publish my scripts to none-ahk users)
so I was always looking for tricks to reduce the memory usage of ahk scripts that i wrote.
but purposeless minimizing window and restoring was the only solution that i 've found so far.
eventually i've found
this article at dotnetSpider while googling.
there were few clues to accomplish my dream. especially
SetProcessWorkingSetSize() API
It was not that rough to realize. but the result was much like magic even with less effort.
However someone in
IRC devaluated it according to
This article.
So i've performed Performance Benchmark hundred times with
DerRaphael's support.
Here's the code that i've used to benchmark it. (derRaphael wrote it. Thanks)
Code:
SetBatchLines, -1
res := ""
t1 := 0, t2 := 0
_t1 := 0, _t2 := 0
iterations := 25
outerLoops := 20
loop, %outerLoops%
{
tooltip, currently @ test: %A_index%
t1 := 0, t2 := 0
Loop, %iterations%
{
VarSetCapacity(Test, 25*1024*1024, 97)
DllCall("QueryPerformanceFrequency", "Int64 *", Freq)
DllCall("QueryPerformanceCounter", "Int64 *", Start)
Loop, 10000
a := chr(NumGet(Test,A_Index,"UChar"))
DllCall("QueryPerformanceCounter", "Int64 *", End)
wo%A_Index% := (End - Start)/Freq
EmptyMem()
DllCall("QueryPerformanceFrequency", "Int64 *", Freq)
DllCall("QueryPerformanceCounter", "Int64 *", Start)
Loop, 10000
a := chr(NumGet(Test,A_Index,"UChar"))
DllCall("QueryPerformanceCounter", "Int64 *", End)
w%A_Index% := (End - Start)/Freq
t1 += wo%A_Index%
t2 += w%A_Index%
}
_t1 += t1/iterations
_t2 += t2/iterations
res .= "Run" a_index ":`tnormal - " t1/iterations "sec`temty() - " t2/iterations "sec`n"
tooltip, currently @ test: A_index
}
res .= "`nAverage normal " _t1/outerLoops " seconds"
. "`nAverage emtpy() " _t2/outerLoops " seconds"
MsgBox,0,Results,%res%
return
EmptyMem(PID="AHK Rocks"){
pid:=(pid="AHK Rocks") ? DllCall("GetCurrentProcessId") : pid
h:=DllCall("OpenProcess", "UInt", 0x001F0FFF, "Int", 0, "Int", pid)
DllCall("SetProcessWorkingSetSize", "UInt", h, "Int", -1, "Int", -1)
DllCall("CloseHandle", "Int", h)
}
here's the result in short for lazy people
If you don't use
SetBatchLine, -1 while calling this function will reduce the performance like only 10ms though i'm still willing to use it.
but if you use
SetBatchLine, -1 there were
NO PERFORMANCE REDUCE for Script. sometimes it's even slightly faster though i don't know why
eg) Results from the benchmark with
SetBatchLine, -1Normal : Average 0.007232 seconds
With Func : Average 0.007195 seconds
as dotnetSpider says. after calling this function memory usage will get larger gradually as scripts claims more mem.
but this can be easily solved by using SetTimer (call this func periodically)
However i've read some posts that are negative to use This func periodically.
If you care, Use it only once at Script startup
Furthermore, you can even reduce the memory usage of external apps such as 3DsMax, Photoshop, IE, etc (even explore.exe)
you might be interest in writing Memory Optimization app by using this function.
but
applying This function to all Processes may potentially degrade the performance of the system. (from MSDN)
and it's not recommendable to use it on Game Processes
however here's the simple but magical function. use at your own risk.
best use of this function is put it
at the end of the AutoExecution Areaor call this function depend on event such as guisize:
Download EmptyMem.ahk to /Lib (Required Win32NT)
Omit parameter to reduce scriptself's mem usage else put target's PID
ExampleCode:
;This example will reduce mem usage from around 5,000k to 500k
Run, taskmgr.exe
MsgBox, Remember current memory usage then compare.
EmptyMem()
Sleep, 5000
Exitapp
EmptyMem(PID="AHK Rocks"){
pid:=(pid="AHK Rocks") ? DllCall("GetCurrentProcessId") : pid
h:=DllCall("OpenProcess", "UInt", 0x001F0FFF, "Int", 0, "Int", pid)
DllCall("SetProcessWorkingSetSize", "UInt", h, "Int", -1, "Int", -1)
DllCall("CloseHandle", "Int", h)
}
PS. i bet Chris will like it if he's still alive
