[Function] VarWrite \ VarRead - A little bit faster alternative to IniWrite \ IniRead [Function]

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
V for Vendetta
Posts: 105
Joined: 29 Sep 2016, 11:33

[Function] VarWrite \ VarRead - A little bit faster alternative to IniWrite \ IniRead [Function]

03 Nov 2016, 21:12

RegEx proved to be too slow for this task, but anyway, "VarWrite \ VarRead" is a little bit faster than "IniWrite \ IniRead"!

- New lines "`r`n" can be stored in the "Keys"

(Extra Files) ListView Control (TickCount Speed Test) \ Edit Controls (New Lines "`r`n" test)

VarWrite \ VarRead (Functions):

Code: Select all

VarWrite(Key := "", Value := "")		;_____________ VarWrite (Function) __________________
{
Static Var	;"Static" variables are always implicitly "local", but differ from "locals" variables because their values are remembered between calls.

	if Key =	;if "Key" is blank
	{
	if Value = GetVar
	return, Var

	Var = %Value%
	return
	}

Value := RegExReplace(Value, "#","##")	;replace any "#" to "##" (Ensures that no String\Character is enclosed by "##")
Value := RegExReplace(Value, "`r`n","#L#")	;replace any New Line "`r`n" to "#L#" (these replacements will be the only String\Character enclosed by "##") 

	If RegExMatch(Var, "m)^" Key "=""(.*)""" , Matched) 	;"m)" Search for a line \ "^" that starts by \ "Key" the string choosed by user \ followed by =" string \ (.*)"" match any string until last " character is found in that line
	{					;All the match wil be stored in "Matched" variable \ the match inside first "( )" will be stored in "Matched1" \ the match inside second "( )" will be stored in "Matched2", and so on ...
	if (Matched1 == Value)				;first " treats second " as literal character \ "= =" case sensitive (a is not A)
	return					;return if the value to be rewritten is the same as the "key" value (Faster this way)

	Value := RegExReplace(Value, "\$", "$$$$")	;replace any "$" to "$$" (necessary because "$" is a special character in RegExReplace 3rd parameter)
					;"\" treats "$" as literal character  -  "$$$$" the first "$" treats the second "$" as literal character, so, "$$$$" = "$$" literal string in RegExReplace 3rd parameter

	Var := RegExReplace(Var, "m)(^" Key "=).*", "$1""" Value """")	;[""], first " treats second " as literal character, so, """" means that there is a literal " character between two Special " characers 
	}						;"$1", in this case, it's a backreference to (^" Key "=) \ $2 would be  a backreference to the second ( ) \ $3 for the 3rd ( ) \ and so on ...
	else						;".*" match any string (the rest of the string left) of that line
	Var = %Var%`r`n%Key%="%Value%"			;"value", the value specified by user
}


VarRead(Key := "", Variable := "")	;_______________ VarRead (Function) ________________
{
Static Var	;"Static" variables are always implicitly "local", but differ from "locals" variables because their values are remembered between calls.

	if Key =	;if "Key" is blank
	{
	Var = %Variable%
	return
	}

RegExMatch(Var, "m)^" Key "=""(.*)""" , Matched)	;"m)" Search for a line \ "^" that starts by \ "Key" the string choosed by user \ followed by  =" string
					;(.*)"" match any string until last " character from that line is found
					;All the match wil be stored in "Matched" variable
					;the match inside first "( )" will be stored in "Matched1"
					;the match inside second "( )" will be stored in "Matched2", and so on ...
					;first " treats second " as literal character

Matched1 := RegExReplace(Matched1, "##(*SKIP)(*F)|#L#", "`r`n")	;replace any "#L#" to "`r`n" (any "##" will be skipped)
Matched1 := RegExReplace(Matched1, "##", "#")		;replace any "##" to "#" (necessary because "VarWrite( )" Function replaces any "#" to "##")

return, Matched1
}
Last edited by V for Vendetta on 10 Nov 2016, 22:31, edited 3 times in total.
guest3456
Posts: 3469
Joined: 09 Oct 2013, 10:31

Re: [Function] VarWrite \ VarRead - A little bit faster alternative to IniWrite \ IniRead [Function]

03 Nov 2016, 21:18

of course its faster, you're storing everything in memory. you could just as easily read the entire ini file first and query all keys from memory just the same. in fact some of the user created ini libraries do that iirc

User avatar
V for Vendetta
Posts: 105
Joined: 29 Sep 2016, 11:33

Re: [Function] VarWrite \ VarRead - A little bit faster alternative to IniWrite \ IniRead [Function]

07 Nov 2016, 12:24

ListView Control (Test Speed - TickCount Added):

1000 Rows:
VarWrite = 468 milliseconds \ VarRead = 499 milliseconds
IniWrite = 32230 milliseconds \ IniRead = 1138 milliseconds

10000 Rows:
VarWrite = 31450 milliseconds \ VarRead = 33946 milliseconds
IniWrite = 400345 milliseconds \ IniRead = 41325 milliseconds
User avatar
DataLife
Posts: 460
Joined: 29 Sep 2013, 19:52

Re: [Function] VarWrite \ VarRead - A little bit faster alternative to IniWrite \ IniRead [Function]

13 Aug 2023, 17:06

I was looking for a way to write case sensitive section labels to an INI file and I came across this.

I believe this is what I need. I will need to write the "var" to a text file and then read that same text file the next time the script is ran.
Basically this stores a case sensitive ini file in memory.

But, I had to change "static Var" to "global var" in both functions to get this to work. What am I missing?

How could the VarRead function work if the VarWrite keeps its "var" local?

Code: Select all

#Persistent
OnExit("ExitFunc")
FileRead,Var,Config.txt

Varwrite("StarLink","Home Internet") ;need to save case sensitive Sections and Keys
Varwrite("STARLINK","HOME INTERNET")

TempVar1 := VarRead("StarLink")
TempVar2 := VarRead("STARLINK")

msgbox,,Ahk %a_linenumber%,  (%TempVar1%)`n(%TempVar2%)
return

ExitFunc(ExitReason, ExitCode)
{
global var
FileDelete,Config.txt
FileAppend,%var%,Config.txt
}

;modified by DataLife for testing - VarWrite function - Changed local Var to global Var
VarWrite(Key := "", Value := "")		;_____________ VarWrite (Function) __________________
{
global Var	;"Static" variables are always implicitly "local", but differ from "locals" variables because their values are remembered between calls.

	if Key =	;if "Key" is blank
	{
	if Value = GetVar
	return, Var

	Var = %Value%
	return
	}

Value := RegExReplace(Value, "#","##")	;replace any "#" to "##" (Ensures that no String\Character is enclosed by "##")
Value := RegExReplace(Value, "`r`n","#L#")	;replace any New Line "`r`n" to "#L#" (these replacements will be the only String\Character enclosed by "##") 

	If RegExMatch(Var, "m)^" Key "=""(.*)""" , Matched) 	;"m)" Search for a line \ "^" that starts by \ "Key" the string choosed by user \ followed by =" string \ (.*)"" match any string until last " character is found in that line
	{					;All the match wil be stored in "Matched" variable \ the match inside first "( )" will be stored in "Matched1" \ the match inside second "( )" will be stored in "Matched2", and so on ...
	if (Matched1 == Value)				;first " treats second " as literal character \ "= =" case sensitive (a is not A)
	return					;return if the value to be rewritten is the same as the "key" value (Faster this way)

	Value := RegExReplace(Value, "\$", "$$$$")	;replace any "$" to "$$" (necessary because "$" is a special character in RegExReplace 3rd parameter)
					;"\" treats "$" as literal character  -  "$$$$" the first "$" treats the second "$" as literal character, so, "$$$$" = "$$" literal string in RegExReplace 3rd parameter

	Var := RegExReplace(Var, "m)(^" Key "=).*", "$1""" Value """")	;[""], first " treats second " as literal character, so, """" means that there is a literal " character between two Special " characers 
	}						;"$1", in this case, it's a backreference to (^" Key "=) \ $2 would be  a backreference to the second ( ) \ $3 for the 3rd ( ) \ and so on ...
	else						;".*" match any string (the rest of the string left) of that line
	Var = %Var%`r`n%Key%="%Value%"			;"value", the value specified by user
}


;modified by DataLife for testing - VarRead function - Changed local Var to global Var
VarRead(Key := "", Variable := "")	;_______________ VarRead (Function) ________________
{
global Var	;"Static" variables are always implicitly "local", but differ from "locals" variables because their values are remembered between calls.
	
	if Key =	;if "Key" is blank
	{
	Var = %Variable%
	return
	}

RegExMatch(Var, "m)^" Key "=""(.*)""" , Matched)	;"m)" Search for a line \ "^" that starts by \ "Key" the string choosed by user \ followed by  =" string
					;(.*)"" match any string until last " character from that line is found
					;All the match wil be stored in "Matched" variable
					;the match inside first "( )" will be stored in "Matched1"
					;the match inside second "( )" will be stored in "Matched2", and so on ...
					;first " treats second " as literal character

Matched1 := RegExReplace(Matched1, "##(*SKIP)(*F)|#L#", "`r`n")	;replace any "#L#" to "`r`n" (any "##" will be skipped)
Matched1 := RegExReplace(Matched1, "##", "#")		;replace any "##" to "#" (necessary because "VarWrite( )" Function replaces any "#" to "##")

return, Matched1
}


Edit 8/15/2023
The opening post does not explain usage.
I studied the functions and here is the usage

Code: Select all

Varwrite("StarLink","Home Internet") 


ConfigVar := Varwrite("","GetVar")
VarRead(,ConfigVar)
TempVar1 := VarRead("StarLink")


msgbox,,Ahk %a_linenumber%,  (%TempVar1%)`n(%TempVar2%)
Before using the VarRead function you have to retrieve the static variable from the VarWrite function, then pass that variable to the read function before attempting to read values from the static variable.

Or make the static variable global and not have to do the extra 2 lines before retrieving values using the VarRead function.
Check out my scripts. (MyIpChanger) (ClipBoard Manager) (SavePictureAs)
All my scripts are tested on Windows 10, AutoHotkey 32 bit Ansi unless otherwise stated.

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: Drugwash and 237 guests