Since AHK allows multiple commands in the same line, the number of lines are not the best measure of the code size. One could count the number of instructions, but that is misleading, too. For example func1(func2(func3,x),y),z) is a single instruction, but it performs 3 function calls.
Skan, your code has the dangerous expression SubStr(Hex, (*++P >> 4), 1) . SubStr(Hex, (*P & 15), 1). There is no guaranty that a future version of AHK will execute ++P before the reference to P in the second SubStr call. It is unlikely, that it will ever be the other way, but you are relying on an undocumented feature of AHK, which might change without a warning. (Documented features change, too, but they are always listed in the change log.)
If you plan to do large hex conversions, you can go one step further, and setup a full byte substitution table outside of the hex conversion function. It could give a little speedup.
Yet another idea was to use the dynamic variable references of AHK, instead of SubStr. It would be interesting to know, which is faster.
Code:
SetFormat Integer, Hex
Loop 256
Hex .= SubStr(A_Index+255,4,2) ; byte table
SetFormat Integer, Dec
Loop 255
H_%A_Index% := SubStr(Hex,2*A_Index+1,2) ; H_0, H_1,...H_255 = 00, 01,...ff
H_0 = 00
toHex1(s:="@AB" chr(1), h, 5)
MsgBox %h%
toHex2(s:="@AB" chr(1), h, 5)
MsgBox %h%
toHex3(s:="@AB" chr(1), h, 5)
MsgBox %h%
toHex0(ByRef b, l = 0) { ; Titan'
f := A_FormatInteger
p := &b
SetFormat, Integer, h
Loop % l ? l : VarSetCapacity(b)
h .= *p++
SetFormat Integer, %f%
Return RegExReplace(RegExReplace(h, "0x(.)(?=0x|$)", "0$1"), "0x")
}
toHex1( ByRef V, ByRef H, dataSz=0) { ; Skan'
P := &V
VarSetCapacity( H, dataSz*2 )
Hex = 123456789ABCDEF0
Loop % dataSz ? dataSz : VarSetCapacity(V)
H .= SubStr(Hex, *P >> 4, 1) . SubStr(Hex, *P++ & 15, 1) ; Danger!
}
toHex2( ByRef V, ByRef H, dataSz=0) { ; Skan**2
Global Hex
P := &V
VarSetCapacity( H, dataSz*2 )
Loop % dataSz ? dataSz : VarSetCapacity(V)
H .= SubStr(Hex, *P++*2+1, 2)
}
toHex3( ByRef V, ByRef H, dataSz=0) { ; Dynamic vars
P := &V
VarSetCapacity( H, dataSz*2 )
Loop % dataSz ? dataSz : VarSetCapacity(V)
i := *P++, H .= H_%i%
}
Most of the running time is spent in the loop, so the fastest algorithm will always be with the simplest instruction in the body of the loop. It is Titan's "h .= *p++", or "h .= *(p+A_Index)" with a prior "p := &V-1". This later version could be slightly faster, because it does not store the incremented value of p.