Over the past few months, I’ve been fine-tuning my skills in AHKv2 and have come across some interesting findings regarding optimization. While exploring, I realized that some of the speed optimization tricks that worked in AHKv1 don’t translate well to AHKv2.
Key Point: In AHKv1, using commas to chain commands and combining lines were common practices to speed up scripts. However, in AHKv2, these methods lead to slower execution, and here’s some speculation:
Command Chaining with Commas: In v1, this technique reduced the number of lines and could potentially speed up execution. In v2, however, the interpreter’s improvements mean that the overhead saved by chaining commands is no longer there. I have found there's actually a speed damper when chaining. It’s important to note that there are exceptions to these observations, and in some specific use cases, you might still see performance benefits in v2.
I've seen some of the old optimization methods used by some of the most experienced v2 writers, so I thought I wrote the DLL call wrong. You can find the v1 tests in the previously mentioned thread and the v2 tests here. I encourage you to replicate these tests and share your findings. I have sat on this for roughly 3 months and posted to the subreddit for scrutiny. Any replicable counters will be shared.
I’ve conducted using the DLLCall query counter, running each in a loop of 55,000 times, checked and rechecked my numbers, and provided places where you can replicate for redundancy. That said, let’s continue to learn and improve together.
The tests
I wrote a helper GUI specificley for this task, it can be found here: https://github.com/samfisherirl/Compare-Code-Speed-GUI-AHKv2
Running similar scripts in debug mode provide a different output.
- It works by calling QueryPerformanceFrequency,
- a loop option for number of executions
- Loop total is split in two (and rounded) and is executed in a snake iteration.
EG if the user has 3 scripts for testing, and the test runs 1000 times, the script executes:
Code: Select all
script1.test1() x500
script2.test1() x500
script3.test1() x500
script3.test2() x500
script2.test2() x500
script1.test2() x500
s1.t1+s1.t2/2
You can find the original AHKv1 optimization thread here: viewtopic.php?f=7&t=6413
This includes credit for @WAZAAAAA viewtopic.php?f=7&t=6413
@jNizM memberlist.php?mode=viewprofile&u=75
@lexikos viewtopic.php?f=7&t=6413
I'm not going to try to rewrite the original post text, a lot of it is great and should be read from the source . Many of the conventions such as #NoEnv and #SetBatchLines are defunct, but the rest is very valuable. I have restructured the tests for ahkv2.
If you would like to replicate the tests in v1 and v2 use the above link and this set of conversions in v2: https://github.com/samfisherirl/Compare-Code-Speed-GUI-AHKv2/tree/main/_speedTestScripts
Combining Expressions on a single line and commas
tests are shortened for brevity, visit above links for complete scripts
Code: Select all
;test 1
t1a := 1
t1b := 1
t1c := 1
t1d := 1
; this continues for a few more lines but I will be abbreviating all duplicates
;test 2
t2f := t2g := t2h := t2i := t2j := 1
;test3
t3a := 1, t3b := 1, t3c := 1, t3d := 1
AHKv1 results =
test1 0.240315
test2 0.132753 ; duplications 50% faster
test3 0.168953 ; ~35% faster using commas compared to multiline
ahkv2 results =
- test1 0.00124844 ; 50% + faster putting variables on separate lines
- test2 0.00259254
- test3 0.00274485
We can see combining variables on a single line in these examples are no longer faster but hamper the code. We'll find out this is different with function calls.
Let's do it again with functions
Code: Select all
; these functions are across all and each test in this trio ; condensed
e() { y := 999*222
return y }
f() { y := 999*222
return y }
g() { y := 999*222
return y }
Code: Select all
; test1 (each function written above)
a := e()
b := f()
c := g()
; test2
a := e(),b := f(),c := g()
;test3
a := e()
,b := f()
,c := g()
- test1 0.01627 (50% slower)
- test2 0.01098
- test3 0.011008
Even shortened conditionals aren't faster with combined lines
Code: Select all
;test1
x := true
if x
z:=1, a:=2, b:=1, c:=2
;test2
x := true
if x
{
z:=1
a:=2
b:=1
c:=2
}
test1 0.0026
test2 0.00180 ;30% faster