How to optimize the speed of a script as much as possible.
Re: How to optimize the speed of a script as much as possible.
Polished the first post quite a bit according to the replies.
-Added details to each command for the skeptic and some corrections.
-SendEvent replaced by SendInput as it seems that I was somehow wrong about Event's higher speed, I benchmarked these again recently and Input was faster like the documentation suggests. Testable benchmark script included into the first post.
-Removed #MaxThreads 255, #MaxMem 4095, #MaxThreadsBuffer On, since lexikos in person clarified that they don't provide any performance benefit. My bad for blindly including them into the code.
-Removed SetTitleMatchMode 2 and SetTitleMatchMode fast because it defaults to fast already and the MatchMode setting was arbitrary.
-Added details to each command for the skeptic and some corrections.
-SendEvent replaced by SendInput as it seems that I was somehow wrong about Event's higher speed, I benchmarked these again recently and Input was faster like the documentation suggests. Testable benchmark script included into the first post.
-Removed #MaxThreads 255, #MaxMem 4095, #MaxThreadsBuffer On, since lexikos in person clarified that they don't provide any performance benefit. My bad for blindly including them into the code.
-Removed SetTitleMatchMode 2 and SetTitleMatchMode fast because it defaults to fast already and the MatchMode setting was arbitrary.
YOU'RE NOT ALEXANDER
Re: How to optimize the speed of a script as much as possible.
WAZAAAAA, your top post still contains the SetKeyDelay error.
"Nothing at all" (for the third parameter) is the more correct option in this case. If you use the word Play it will only affect SendPlay, which defaults to -1/-1 anyway.Sam_ wrote:Thanks for the catch! I updated my last post.lexikos wrote:The third parameter should be the word "Play" or nothing at all. -1 has no meaning.SetKeyDelay, -1, -1, -1
- Joe Glines
- Posts: 771
- Joined: 30 Sep 2013, 20:49
- Location: Dallas
- Contact:
Re: How to optimize the speed of a script as much as possible.
Thanks for y'all working on this. I put something similar to the above in my library and then I call it at the beginning of all my scripts:
#Include <default_Settings>
This allows me to keep my script small yet have a lot of preferences selected. (I just like having less in my actual file )
#Include <default_Settings>
This allows me to keep my script small yet have a lot of preferences selected. (I just like having less in my actual file )
Sign-up for the HK Newsletter
AHK Tutorials:Web Scraping | | Webservice APIs | AHK and Excel | Chrome | RegEx | Functions
Training: AHK Webinars Courses on AutoHotkey
YouTube
Quick Access Popup, the powerful Windows folders, apps and documents launcher!
AHK Tutorials:Web Scraping | | Webservice APIs | AHK and Excel | Chrome | RegEx | Functions
Training: AHK Webinars Courses on AutoHotkey
YouTube
Quick Access Popup, the powerful Windows folders, apps and documents launcher!
Re: How to optimize the speed of a script as much as possible.
corrected, thanks for pointing it out again, and thanks for EXISTINGlexikos wrote:WAZAAAAA, your top post still contains the SetKeyDelay error."Nothing at all" (for the third parameter) is the more correct option in this case. If you use the word Play it will only affect SendPlay, which defaults to -1/-1 anyway.Sam_ wrote:Thanks for the catch! I updated my last post.lexikos wrote:The third parameter should be the word "Play" or nothing at all. -1 has no meaning.SetKeyDelay, -1, -1, -1
YOU'RE NOT ALEXANDER
Re: How to optimize the speed of a script as much as possible.
Is it okay to discuss programming techniques that will help "optimize the speed of a script as much as possible" in this topic? For instance, in my experience (and according to the documentation), using VarSetCapacity() improves performance when building a string by means of gradual concatenation. From the documentation:
From the example in the documentation (although not a working example...):In addition to its uses described at DllCall, this function can also be used to enhance performance when building a string by means of gradual concatenation. This is because multiple automatic resizings can be avoided when you have some idea of what the string's final length will be.
Code: Select all
; Optimize by ensuring MyVar has plenty of space to work with.
VarSetCapacity(MyVar, 10240000) ; ~10 MB
Loop
{
...
MyVar = %MyVar%%StringToConcatenate%
...
}
Re: How to optimize the speed of a script as much as possible.
Yes, as the first post mentions:Sam_ wrote:Is it okay to discuss programming techniques that will help "optimize the speed of a script as much as possible" in this topic
WAZAAAAA wrote:GOTTA GO FAST
YOU'RE NOT ALEXANDER
- KuroiLight
- Posts: 327
- Joined: 12 Apr 2015, 20:24
- Contact:
Re: How to optimize the speed of a script as much as possible.
Looks good.Sam_ wrote:So, taking the above into account, following the recommendations in the documentation (generally a wise move), and rearranging a bit, we now have:
Edited SetKeyDelay. See next post.Code: Select all
#NoEnv Process, Priority, , H SetBatchLines, -1 ListLines Off #KeyHistory 0 SendMode Input SetTitleMatchMode 2 SetTitleMatchMode Fast SetKeyDelay, -1, -1, Play SetMouseDelay, -1 SetWinDelay, 0 ; Changed to 0 upon recommendation of documentation SetControlDelay, 0 ; Changed to 0 upon recommendation of documentation SetDefaultMouseSpeed, 0 ; YOUR_SCRIPT_HERE
Windows 10, Ryzen 1600, 16GB G.Skill DDR4, 8GB RX 480 | [MyScripts][MySublimeSettings] [Unlicense][MIT License]
01/24/18
[/color]Re: How to optimize the speed of a script as much as possible.
Speedup DllCall's (excluded: "User32.dll", "Kernel32.dll", "ComCtl32.dll" & "Gdi32.dll")
Found in old Forum (Code by Bentschi)
Functions: LoadLibrary() & FreeLibrary()
Test Script:
Result:
Export Table:
Maybe Lexikos can tell us more about it and his pro & contra.
Found in old Forum (Code by Bentschi)
Functions: LoadLibrary() & FreeLibrary()
Code: Select all
LoadLibrary(filename)
{
static ref := {}
if (!(ptr := p := DllCall("LoadLibrary", "str", filename, "ptr")))
return 0
ref[ptr,"count"] := (ref[ptr]) ? ref[ptr,"count"]+1 : 1
p += NumGet(p+0, 0x3c, "int")+24
o := {_ptr:ptr, __delete:func("FreeLibrary"), _ref:ref[ptr]}
if (NumGet(p+0, (A_PtrSize=4) ? 92 : 108, "uint")<1 || (ts := NumGet(p+0, (A_PtrSize=4) ? 96 : 112, "uint")+ptr)=ptr || (te := NumGet(p+0, (A_PtrSize=4) ? 100 : 116, "uint")+ts)=ts)
return o
n := ptr+NumGet(ts+0, 32, "uint")
loop % NumGet(ts+0, 24, "uint")
{
if (p := NumGet(n+0, (A_Index-1)*4, "uint"))
{
o[f := StrGet(ptr+p, "cp0")] := DllCall("GetProcAddress", "ptr", ptr, "astr", f, "ptr")
if (Substr(f, 0)==((A_IsUnicode) ? "W" : "A"))
o[Substr(f, 1, -1)] := o[f]
}
}
return o
}
FreeLibrary(lib)
{
if (lib._ref.count>=1)
lib._ref.count -= 1
if (lib._ref.count<1)
DllCall("FreeLibrary", "ptr", lib._ptr)
}
Code: Select all
loops := 1000000
SetBatchLines, -1
global gdiplus := LoadLibrary("gdiplus")
VarSetCapacity(bin, 20, 0)
NumPut(1, bin, 0, "int")
DllCall(gdiplus.GdiplusStartup, "ptr*", token, "ptr", &bin, "ptr", 0)
DllCall(gdiplus.GdipCreateBitmapFromScan0, "int", 1, "int", 1, "int", 0, "int", 0x26200A, "ptr", 0, "ptr*", pBitmap)
start := A_TickCount
loop % loops
DllCall("gdiplus\GdipBitmapGetPixel", "ptr", pBitmap, "int", 1, "int", 1, "uint*", col)
timeA := A_TickCount-start
start := A_TickCount
loop % loops
DllCall(gdiplus.GdipBitmapGetPixel, "ptr", pBitmap, "int", 1, "int", 1, "uint*", col)
timeB := A_TickCount-start
DllCall(gdiplus.DisposeImage, "ptr", pBitmap)
DllCall(gdiplus.Cleanup, "ptr", token)
MsgBox % "Normal:`n" timeA "`n`nWith LoadLibrary:`n" timeB "`n`n" timeA/timeB
Code: Select all
---------------------------
LoadLibrary.ahk
---------------------------
Normal:
1828
With LoadLibrary:
781
2.340589
---------------------------
OK
---------------------------
Code: Select all
global gdiplus := LoadLibrary("gdiplus")
for name, proc in gdiplus
{
if (name!="_ptr" && name!="_ref" && name!="__delete")
MsgBox % name
}
Maybe Lexikos can tell us more about it and his pro & contra.
Last edited by jNizM on 06 Jul 2015, 01:46, edited 1 time in total.
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
Re: How to optimize the speed of a script as much as possible.
Posts by Sam_ and jNizM added to the top
YOU'RE NOT ALEXANDER
- KuroiLight
- Posts: 327
- Joined: 12 Apr 2015, 20:24
- Contact:
Re: How to optimize the speed of a script as much as possible.
why not this?jNizM wrote:Spoiler
Code: Select all
LUCall(lib, func, params*) {
static LookupTable := {}
if(!Lookuptable[lib][func]) {
if(!LookupTable[lib])
LookupTable[lib] := {}
LookupTable[lib][func] := DllCall("GetProcAddress", Ptr, DllCall("LoadLibrary", Str, lib, Ptr), AStr, func, Ptr)
}
return DllCall(LookupTable[lib][func], params*)
}
Code: Select all
LUCall("Kernel32", "Sleep", "Int", 1000)
LUCall("User32", "MessageBoxA", "UInt", 0, "AStr", "Hello World!", "AStr", "MSGBOX", "UInt", 0)
LUCall("Kernel32", "Sleep", "Int", 1000)
Spoiler
EDIT: well seems I made a mistake in not testing these properly before-hand: in that all other ways I've tried are still slower than the built-in dllcall, makes sense actually. (guess Ill be removing some code); I still think one form or another might help with function calls to libraries not yet loaded though, stay clear of lookuptables/dictionaries as those seem to be too slow for ahk though. (strangely enough dynamic variable version was the fastest of the 3)
Spoiler
Windows 10, Ryzen 1600, 16GB G.Skill DDR4, 8GB RX 480 | [MyScripts][MySublimeSettings] [Unlicense][MIT License]
01/24/18
[/color]Re: How to optimize the speed of a script as much as possible.
As suggested by the documentation I have changedDocumentation wrote:Performance: In v1.0.48+, the comma operator is usually faster than writing separate expressions, especially when assigning one variable to another (e.g. x:=y, a:=b). Performance continues to improve as more and more expressions are combined into a single expression; for example, it may be 35% faster to combine five or ten simple expressions into a single expression.
Code: Select all
a := 1
b := 2
c := 3
d := Function( param )
e := AnotherFunc( d )
return
Code: Select all
a := 1
, b := 2
, c := 3
, d := Function( param )
, e := AnotherFunc( d )
return
Re: How to optimize the speed of a script as much as possible.
@dd900
Thats what I posted here => Speed Test (Benchmark): Define Variables
Thats what I posted here => Speed Test (Benchmark): Define Variables
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
Re: How to optimize the speed of a script as much as possible.
It's not too surprising that those DLLCalls are slower. Those particular function names are automatically resolved to an address when AHK starts. Better results might be obtained when the function does not reside in User32.dll, Kernel32.dll, ComCtl32.dll, or Gdi32.dll.KuroiLight wrote: EDIT: well seems I made a mistake in not testing these properly before-hand: in that all other ways I've tried are still slower than the built-in dllcall, makes sense actually. (guess Ill be removing some code); I still think one form or another might help with function calls to libraries not yet loaded though, stay clear of lookuptables/dictionaries as those seem to be too slow for ahk though. (strangely enough dynamic variable version was the
However, I use the GDIP ahk library and decided to try jNizM's idea.
Test:
All the gdiPlus names were replaced with an object that stored the relevant function address.
A custom drawing function was then looped 1000 times.
Average Time Per Loop:
- String Function Name: 14.9 ms
Function Address: 15.5 ms
Re: How to optimize the speed of a script as much as possible.
@RHCP
Can you show me your testscript?
Can you show me your testscript?
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
Re: How to optimize the speed of a script as much as possible.
Replaced the high CPU Sleep function with the "suspend" Sleep method which uses no considerable CPU and makes the code way shorter.
Here's the previous one, for historical reasons I guess:
Here's the previous one, for historical reasons I guess:
Spoiler
YOU'RE NOT ALEXANDER
Re: How to optimize the speed of a script as much as possible.
Higher precision but higher usage ?WAZAAAAA wrote:Replaced the high CPU Sleep function with the "suspend" Sleep method which uses no considerable CPU and makes the code way shorter.
Here's the previous one, for historical reasons I guess:Spoiler
And may I ask.
What's the lowest delay of the function
Re: How to optimize the speed of a script as much as possible.
According to my benchmarks:dsewq1LYJ wrote:Higher precision but higher usage ?
And may I ask.
What's the lowest delay of the function
Sleep default method = low CPU, low precision
Sleep suspend method = low CPU, high precision, issues with SetTimer
Sleep precise method = high CPU, higher precision
But sometimes when using the precise method, it eats so much CPU that it actually ends up slowing everything down, this has happened to a friend of mine too with a weaker PC, that's why I have replaced it with the suspend mode.
You can read more about precise sleeps at RHCP's thread: http://www.autohotkey.com/board/topic/9 ... -function/
I don't understand what do you mean with lowest delay.
YOU'RE NOT ALEXANDER
Re: How to optimize the speed of a script as much as possible.
HiWAZAAAAA wrote:According to my benchmarks:dsewq1LYJ wrote:Higher precision but higher usage ?
And may I ask.
What's the lowest delay of the function
Sleep default method = low CPU, low precision
Sleep suspend method = low CPU, high precision, issues with SetTimer
Sleep precise method = high CPU, higher precision
But sometimes when using the precise method, it eats so much CPU that it actually ends up slowing everything down, this has happened to a friend of mine too with a weaker PC, that's why I have replaced it with the suspend mode.
You can read more about precise sleeps at RHCP's thread: http://www.autohotkey.com/board/topic/9 ... -function/
I don't understand what do you mean with lowest delay.
Waza
As you say in this thread.
http://ahkscript.org/boards/viewtopic.php?t=5920
The PixelSearch is faster than PixelGetColor.
but I got a Question about it.
The "PixelSearch" cant store the color right ?
What I mean...is follow code maybe the PixelSearch is pointless ?
<Sorry about my horrible English...I'll try my best...>
e.g.
Code: Select all
;PixelGetColor
PixelGetColor,A,1,1
PixelGetColor,B,2,2
PixelGetColor,C,3,3
if (A=0xFFFFFF)
foo()
else if (B=0xEEEEEE)
bar()
else if (C=0xDDDDDD)
foo()
; Uh...How and .... what ?
PixelSearch,,,1,1,1,1,0xFFFFFF
PixelSearch,,,1,1,1,1,0xEEEEEE
PixelSearch,,,1,1,1,1,0xDDDDDD
;Gdi ? Faster
;....
Re: How to optimize the speed of a script as much as possible.
If I understand well something like this:
Code: Select all
PixelSearch,,,1,1,1,1,0xFFFFFF
if !errorlevel
foo()
PixelSearch,,,1,1,1,1,0xEEEEEE
if !errorlevel
bar()
PixelSearch,,,1,1,1,1,0xDDDDDD
if !errorlevel
foo()
Re: How to optimize the speed of a script as much as possible.
ozzii wrote:If I understand well something like this:Code: Select all
PixelSearch,,,1,1,1,1,0xFFFFFF if !errorlevel foo() PixelSearch,,,1,1,1,1,0xEEEEEE if !errorlevel bar() PixelSearch,,,1,1,1,1,0xDDDDDD if !errorlevel foo()
Nice..but I still confusing ... Why PixelSearch faster than PixelGetColor ???...
PixelSearch has 7 parameters ... why it faster !?
Who is online
Users browsing this forum: No registered users and 12 guests