Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

v1.0.46 released: SubStr() and more expression operators


  • Please log in to reply
63 replies to this topic
Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Here are the changes for v1.0.46.06:

Applied minor fixes and improvements to regular expressions by upgrading from PCRE 6.7 to 7.0. One of the most notable improvements is the `a option, which recognizes any type of newline (namely `r, `n, or `r`n). Similarly, the \R escape sequence means "any single newline of any type". See also: Full PCRE changelog

Changed and fixed all Control commands and StatusBarWait to obey SetTitleMatchMode RegEx as documented.

Changed RegExReplace() to return the original/unaltered string rather than "" when an error occurs.

Changed: Enabled the Terminal Server Awareness flag on AutoHotkey.exe and compiled scripts.

Improved performance when assigning large strings returned from user-defined functions. [thanks Laszlo]

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005

Improved performance when assigning large strings returned from user-defined functions.

Could you give an example, when this speedup is noticeable? The simple test script I used did not show any change.
SetBatchLines -1

Process Priority,,R



tf := A_TickCount

x := f()

tf -= A_TickCount

tg := A_TickCount

g(z)

tg -= A_TickCount



MsgBox % "Return: " . -tf . "`nByRef: " . -tg ; 200 / 60 ms



f() {

   VarSetCapacity(x,50000000,120)

   Return x

}



g(ByRef x) {

   VarSetCapacity(x,50000000,120)

}


Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
If a user-defined function returns one of its local variables, that isn't fully optimized yet. But if it returns an expression that requires temporary memory (and most non-trivial ones do), that is where the new optimization comes in.

I ran the following revised script on the new .06 vs. the old .05:
#NoEnv
SetBatchLines -1 

tf := A_TickCount 
x := f() 
tf -= A_TickCount 
tg := A_TickCount 
g(z) 
tg -= A_TickCount 

MsgBox % "Return: " . -tf . "`nByRef: " . -tg ; 200 / 60 ms 

f() { 
   VarSetCapacity(x,50000000,120) 
   Return SubStr(x, 1)
} 

g(ByRef x) { 
   VarSetCapacity(x,50000000,120) 
   x := SubStr(x, 1)
}
New .06:
721
181

Old .05:
1512
211

So on my system, the first test ("return") is about twice as fast on the new .06 as the old .05, which makes sense because I think exactly one of two memory copying steps is saved. By the way, I used SubStr() in this test because it is known to use almost no CPU time when called in this way. In other words, it is one of the least expensive "non-trivial expressions".

Hopefully the local variable optimization will be done someday (e.g. "return x"). But if this last optimization was any indication, it will take several hours to do properly, with a high risk of introducing new bugs. However, benchmarks show that "return x" is already quite a bit faster than returning a complex expression, which implies that the existing code is already pretty fast and might not benefit as much from the planned optimization as it did from this most recent one.

Finally, I realize that "return" is still much slower than ByRef. That is expected because it is difficult to have complete prediction, integration, and optimization without a lot of extra code, which reduces maintainability.

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
In my PC I got 250/78 ms running time with your script above. It is interesting, because SubStr introduced 48 ms extra running time in the Return version (over a simple Return x), but only 16 ms in the ByRef variant (3 times less). Looks like x := SubStr(x, 1) is faster than temp := SubStr(x, 1).

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
It might not be SubStr itself that produces this discrepancy, but the fact that SubStr() is a function-call, and thus a non-trivial expression that requires temporary memory. By contrast, "return x" doesn't require any temporary memory, so there are many existing savings already in effect.

Looks like x := SubStr(x, 1) is faster than temp := SubStr(x, 1).

Yes, there is an optimization that detects when a variable is being assigned something that resolves to itself.

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
These two give almost the same running time:
f() {

   VarSetCapacity(x,50000000,120)

   Return SubStr(x, 1)

}



g(ByRef x) {

   VarSetCapacity(y,50000000,120)

   x := SubStr(y, 1)

}


Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Yes, the first one copies into temporary memory (as part of "return"), but the second one copies directly into X. Since both incur one mem-copy, i would expect the same performance (perhaps depending on how they're called, since only assignments have the new optimization that takes ownership of temporary memory).

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Here are the changes for v1.0.46.07:

Fixed crash of an illegally-named dynamic variable on the left of an equal-sign assignment (broken by 1.0.45). [thanks PhiLho]

Fixed FileMoveDir's "Option 2" to work properly even when the directory is being both renamed and moved. [thanks bugmenot]

Fixed inability to pass a variable ByRef if that same expression changed it from empty to non-empty (when #NoEnv is absent). [thanks Joy2DWorld]

Changed DllCall's A_LastError to reflect only changes made by the script, not by AutoHotkey itself. [thanks Azerty]

AHKnow*
  • Guests
  • Last active:
  • Joined: --

Wow! These changes should warrant a new subversion number. How about v1.1.0? Scripts will look drastically different with the new syntax enhancements...


I agree. The look of newer AutoHotkey scripts can now be very different than they looked in the past.

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Here are the changes for v1.0.46.08:

Fixed unreliability of ComSpec and environment variables on Windows 9x (broken by v1.0.46.07). [thanks Loriss]

Changed the Terminal Server Awareness flag back to "disabled" on AutoHotkey.exe and compiled scripts. This improves flexibility and backward compatibility (see <!-- m -->http://www.autohotke...pic.php?t=16041<!-- m -->).

Changed: When AutoHotkey.exe is launched without a script specified, it will now run (or prompt you to create) the file AutoHotkey.ahk in the My Documents folder. The only exception is when AutoHotkey.ini exists in the working directory, in which case it uses the old behavior of executing that file.

Improved DllCall to support an integer in place of the function name, which is interpreted as the address of the function to call. [thanks Sean]

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Here are the changes for v1.0.46.09:

Fixed ":=" deep inside expressions when used to assign the result of a recursive function to a local variable (broken by 1.0.46.06). [thanks Laszlo]

Fixed inability to pass certain ternary expressions to ByRef parameters. [thanks Titan]

Fixed "GuiControlGet, OutputVar, Pos" so that it doesn't make the OutputVar blank. [thanks PhiLho]

Changed and fixed continuation sections so that the "Comment" option doesn't force the LTrim option into effect. [thanks Titan]

Changed the Terminal Server Awareness flag back to "disabled" on AutoHotkey.exe and compiled scripts. This improves flexibility and backward compatibility (see discussion at forum).

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Here are the changes for v1.0.46.10:

Fixed StringSplit inside assume-local functions so that it creates a local array even when OutputArray0 exists as a global but not a local. [thanks KZ]

Improved ListView's item-changed notification ("I") to indicate via ErrorLevel whether the item has been selected/deselected, focused/unfocused, and/or checked/unchecked. [thanks foom]

Added an additional layer of protection to compiled scripts. It is recommended that scripts containing sensitive data or source code be recompiled with the /NoDecompile switch.

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Here are the changes for v1.0.46.11:

Fixed inability to have a function-call as the first item in certain comma-separated expressions. [thanks Majkinetor]

Fixed WinTitles like "ahk_id %ControlHwnd%" in ControlGet's FindString/Choice/List, and Control's Add/Delete/Choose. [thanks Freighter & PhiLho]

Improved floating point support to recognize scientific notation; e.g. 1.2e-5 (the decimal point is mandatory). Also improved "SetFormat Float" with an option to output in scientific notation. [thanks Laszlo]

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
Thank, Chris! I am very happy with the scientific format. There is no need any more to count digits before floating point computations. Great! (Although there is a little problem with 0.15e+1)

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
In v1.0.46.12, the inability to recognize a literal scientific notation number that begins with 0, such as 0.15e+1, has been fixed. [thanks Laszlo]