I want to optimize my script.

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
whynotregister
Posts: 147
Joined: 05 Nov 2016, 22:42

I want to optimize my script.

28 Dec 2017, 10:59

Here is an example of the script you are using.

Code: Select all

point := 1.5

loop
{
random,ran,-1.5,2.5
random,ran2,1~100
var .= ran "ID" ran2"`n"
if a_index = 7
break
}

; The above loop statement is not important. Only numbers that accumulate in var are important.
; Then, in the "var" variable, find the number closest to the "point" variable and try to find the corresponding ID.

        loop,parse,var,`n
        {
            stringgetpos,var2,a_loopfield,ID
            stringleft,var3,a_loopfield,%var2%
            var4 .= var3 "`n"
        }
        
         ;  Only the decimal point values ​​in the var variable are stored in var4.
        
        for i, v in StrSplit(RTrim(var4,  "`n"), "`n", "`n")
        {
            if(!smallest_diff or (Abs(point - v) < smallest_diff))
            {
                smallest_diff := Abs(point - v)
                best_candidate := v
            }
        }
           
         ; Then find the closest match to the "point" variable in the "var4" variable.

        loop,parse,var,`n
        {
            checkvar2 := a_loopfield
            ifinstring,checkvar2,%best_candidate%
            {
                stringgetpos,checkvar2,checkvar2,ID
                checkvar2 := checkvar2+2
                stringtrimleft,checkvar3,a_loopfield,%checkvar2%
                break
            }
        }

        ; Now that have the closest number get the id.
I think that the rest of the code is inefficient, except for the part for best_candidate.
I would like to get help from the forum users and fix it with faster and optimized code.
Last edited by whynotregister on 28 Dec 2017, 20:32, edited 2 times in total.
User avatar
divanebaba
Posts: 813
Joined: 20 Dec 2016, 03:53
Location: Diaspora

Re: I want to optimize my script.

28 Dec 2017, 13:45

whynotregister wrote:... I think that the rest of the code is inefficient, except for the part for best_candidate. ...
I think I've found a bit of redundant code in your best_candidate part.
I would code this part like below:

Code: Select all

loop,parse,var,`n, `r ; <-- help file recommends to skip linefeed (`r)
	{
		; checkvar2 := a_loopfield ; <--- this is redundant part inside your code. Delete it and change your code like below
		ifinstring,a_loopfield,%best_candidate%
		{
			stringgetpos,checkvar2,a_loopfield,ID
			checkvar2 := checkvar2+2
			stringtrimleft,checkvar3,a_loopfield,%checkvar2%
			break
		}
	}
Einfach nur ein toller Typ. :mrgreen:
whynotregister
Posts: 147
Joined: 05 Nov 2016, 22:42

Re: I want to optimize my script.

28 Dec 2017, 19:10

divanebaba wrote:
whynotregister wrote:... I think that the rest of the code is inefficient, except for the part for best_candidate. ...
I think I've found a bit of redundant code in your best_candidate part.
I would code this part like below:

Code: Select all

loop,parse,var,`n, `r ; <-- help file recommends to skip linefeed (`r)
	{
		; checkvar2 := a_loopfield ; <--- this is redundant part inside your code. Delete it and change your code like below
		ifinstring,a_loopfield,%best_candidate%
		{
			stringgetpos,checkvar2,a_loopfield,ID
			checkvar2 := checkvar2+2
			stringtrimleft,checkvar3,a_loopfield,%checkvar2%
			break
		}
	}

thank you. Is there a faster way to find IDs more fundamentally?
flatwater
Posts: 7
Joined: 28 Dec 2017, 08:21

Re: I want to optimize my script.

29 Dec 2017, 00:38

Code: Select all

point := 1.5

loop 7
{
    random,ran,-1.5,2.5
    random,ran2,1~100
    var .= ran "ID" ran2 "`n"
}

while p := RegexMatch(var,"i)(\S+?)ID",m,a_index=1?1:p+strlen(m))
    dec_val .= m1 "`n"
loop, parse, dec_val, `n
    if a_loopfield is not space
    {
        if(!smallest_diff or (Abs(point - a_loopfield) < smallest_diff))
        {
            smallest_diff := Abs(point - a_loopfield)
            best_candidate := a_loopfield
        }
    }

RegExMatch(var,best_candidate "ID(\S+)",m)

MsgBox % var "`n" best_candidate "`nID: " m1
whynotregister
Posts: 147
Joined: 05 Nov 2016, 22:42

Re: I want to optimize my script.

29 Dec 2017, 07:39

flatwater wrote:

Code: Select all

point := 1.5

loop 7
{
    random,ran,-1.5,2.5
    random,ran2,1~100
    var .= ran "ID" ran2 "`n"
}

while p := RegexMatch(var,"i)(\S+?)ID",m,a_index=1?1:p+strlen(m))
    dec_val .= m1 "`n"
loop, parse, dec_val, `n
    if a_loopfield is not space
    {
        if(!smallest_diff or (Abs(point - a_loopfield) < smallest_diff))
        {
            smallest_diff := Abs(point - a_loopfield)
            best_candidate := a_loopfield
        }
    }

RegExMatch(var,best_candidate "ID(\S+)",m)

MsgBox % var "`n" best_candidate "`nID: " m1

Thank you. For your help
A_AhkUser
Posts: 1147
Joined: 06 Mar 2017, 16:18
Location: France
Contact:

Re: I want to optimize my script.

29 Dec 2017, 13:12

Here's a alternative solution using a variadic call of the brand new min function (that is, it works only with ahk v1.1.27.00 aka :xmas: Xmas edition or greater).

It simply splits inputvar using 'ID' and '`n' as delimiters then build a string using a loop, string where the discrepancy is put side by side with its respective ID. Then, it retrieves, using min function, the bestCandidate occurrence in the string before retrieving the ID alongside it (in particular, without the need to use a regex).

Code: Select all

var =
(
-0.186502ID1693735784
-1.087232ID221352170
1.214623ID398215325
-1.388897ID699966223
1.484426ID908915416
2.497012ID2092217243
2.538931ID1970748420
)
point := 1.5

MsgBox % bestCandidate(var, point)


bestCandidate(__list, __point) {
vArray1 := StrSplit(__list, ["ID", "`n"]), vString := "|", vAvArray2 := [], i := 0
Loop % vArray1.length()//2
	vString .= (vAvArray2[ a_index ] := Abs(__point - vArray1[++i])) . "|" . vArray1[++i] . "|"
return SubStr(vString, InStr(vString, "|" . min(vAvArray2*) . "|") + StrLen(vArray1[1]) + 1, StrLen(vArray1[2]) - 1)
}
my scripts
whynotregister
Posts: 147
Joined: 05 Nov 2016, 22:42

Re: I want to optimize my script.

30 Dec 2017, 02:41

A_AhkUser wrote:Here's a alternative solution using a variadic call of the brand new min function (that is, it works only with ahk v1.1.27.00 aka :xmas: Xmas edition or greater).

It simply splits inputvar using 'ID' and '`n' as delimiters then build a string using a loop, string where the discrepancy is put side by side with its respective ID. Then, it retrieves, using min function, the bestCandidate occurrence in the string before retrieving the ID alongside it (in particular, without the need to use a regex).

Code: Select all

var =
(
-0.186502ID1693735784
-1.087232ID221352170
1.214623ID398215325
-1.388897ID699966223
1.484426ID908915416
2.497012ID2092217243
2.538931ID1970748420
)
point := 1.5

MsgBox % bestCandidate(var, point)


bestCandidate(__list, __point) {
vArray1 := StrSplit(__list, ["ID", "`n"]), vString := "|", vAvArray2 := [], i := 0
Loop % vArray1.length()//2
	vString .= (vAvArray2[ a_index ] := Abs(__point - vArray1[++i])) . "|" . vArray1[++i] . "|"
return SubStr(vString, InStr(vString, "|" . min(vAvArray2*) . "|") + StrLen(vArray1[1]) + 1, StrLen(vArray1[2]) - 1)
}

There is an error. The above code returns 908915416.
A_AhkUser
Posts: 1147
Joined: 06 Mar 2017, 16:18
Location: France
Contact:

Re: I want to optimize my script.

30 Dec 2017, 16:48

Hi whynotregister,
There is an error. The above code returns 908915416.
It returns 908915416 (1.484426's ID) because 1.484426 is the number the most proximate to 1.5 (point). Is this not what you was expecting?

[EDIT]
Ok I see the problem: in var some numbers are 9-digit numbers while others are 10-digit. I guess in this case a regex is unavoidable:

Code: Select all

bestCandidate(__list, __point) {
vArray1 := StrSplit(__list, ["ID", "`n"]), vString := "|", vAvArray2 := [], i := 0
Loop % vArray1.length()//2
	vString .= (vAvArray2[ a_index ] := Abs(__point - vArray1[++i])) . "|" . vArray1[++i] . "|"
RegExMatch(vString, "(?<=\|" . min(vAvArray2*) . "\|).+?(?=\|)", match)
return match
}
my scripts
whynotregister
Posts: 147
Joined: 05 Nov 2016, 22:42

Re: I want to optimize my script.

31 Dec 2017, 01:47

A_AhkUser wrote:Hi whynotregister,
There is an error. The above code returns 908915416.
It returns 908915416 (1.484426's ID) because 1.484426 is the number the most proximate to 1.5 (point). Is this not what you was expecting?

[EDIT]
Ok I see the problem: in var some numbers are 9-digit numbers while others are 10-digit. I guess in this case a regex is unavoidable:

Code: Select all

bestCandidate(__list, __point) {
vArray1 := StrSplit(__list, ["ID", "`n"]), vString := "|", vAvArray2 := [], i := 0
Loop % vArray1.length()//2
	vString .= (vAvArray2[ a_index ] := Abs(__point - vArray1[++i])) . "|" . vArray1[++i] . "|"
RegExMatch(vString, "(?<=\|" . min(vAvArray2*) . "\|).+?(?=\|)", match)
return match
}

Thanks for the good answer. :D
User avatar
KuroiLight
Posts: 327
Joined: 12 Apr 2015, 20:24
Contact:

Re: I want to optimize my script.

31 Dec 2017, 03:13

You should avoid using strings like this altogether, an Array is more appropriate and likely faster for the interpreter.
If you need to split a string list of values and rejoin them after, use StrSplit and Format.
Though it seems you found your answer.
Windows 10, Ryzen 1600, 16GB G.Skill DDR4, 8GB RX 480 | [MyScripts][MySublimeSettings] [Unlicense][MIT License]
01/24/18
[/color]

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: DracoCapt, Rohwedder and 92 guests