A_TickCount to use GetTickCount64 instead of GetTickCount

Propose new features and changes
User avatar
jNizM
Posts: 2665
Joined: 30 Sep 2013, 01:33
GitHub: jNizM
Contact:

Re: A_TickCount to use GetTickCount64 instead of GetTickCoun

24 Sep 2014, 05:26

just use tc := DllCall("Kernel32.dll\GetTickCount64", "UInt64")
[AHK] 1.1.32.00 x64 Unicode | [WIN] 10 Pro (Version 2004) x64 | [GitHub] Profile
Donations are appreciated if I could help you
User avatar
Raccoon
Posts: 53
Joined: 26 Jul 2014, 16:15

Re: A_TickCount to use GetTickCount64 instead of GetTickCoun

24 Sep 2014, 05:35

Thank you jNizM. This is a WishList request for the betterment of AutoHotkey's development.

GetTickCount is deprecated and should be replaced with GetTickCount64 for modern builds of AHK_L where applicable.

GetTickCount on MSDN

GetTickCount64 on MSDN
User avatar
jNizM
Posts: 2665
Joined: 30 Sep 2013, 01:33
GitHub: jNizM
Contact:

Re: A_TickCount to use GetTickCount64 instead of GetTickCoun

24 Sep 2014, 05:39

See the Minimum Support

GetTickCount function
Retrieves the number of milliseconds that have elapsed since the system was started, up to 49.7 days.
Minimum supported client: Windows 2000 Professional
Minimum supported server: Windows 2000 Server

GetTickCount64 function
Retrieves the number of milliseconds that have elapsed since the system was started.
Minimum supported client: Windows Vista
Minimum supported server: Windows Server 2008

timeGetTime function
The timeGetTime function retrieves the system time, in milliseconds. The system time is the time elapsed since Windows was started.
Minimum supported client: Windows 2000 Professional
Minimum supported server: Windows 2000 Server

=========================================================

Test Script

Code: Select all

WinAPI_timeBeginPeriod(1)
sleep 1000
buf := "-------------------`n"
loop 30
{
	tc := WinAPI_GetTickCount()
	loop
	{
		dt := WinAPI_GetTickCount() - tc
		if (dt >= 1)
		{
			buf .= A_Index . "  " . dt . "`n"
			break
		}
	}
}
buf .= "-------------------`n"
sleep 1000
loop 30
{
	tc := WinAPI_timeGetTime()
	loop
	{
		dt := WinAPI_timeGetTime() - tc
		if (dt >= 1)
		{
			buf .= A_Index . "  " . dt . "`n"
			break
		}
	}
}
WinAPI_timeEndPeriod(1)
MsgBox % buf
ExitApp


WinAPI_GetTickCount()    ; http://msdn.microsoft.com/en-us/library/ms724408.aspx
{
    return DllCall("kernel32.dll\GetTickCount", "UInt")
}

WinAPI_timeGetTime()    ; http://msdn.microsoft.com/en-us/library/dd757629.aspx
{
    return DllCall("Winmm.dll\timeGetTime", "UInt")
}

WinAPI_timeBeginPeriod(uPeriod)    ; http://msdn.microsoft.com/en-us/library/dd757624.aspx
{
    return DllCall("Winmm.dll\timeBeginPeriod", "UInt", uPeriod, "UInt")
}

WinAPI_timeEndPeriod(uPeriod)    ; http://msdn.microsoft.com/en-us/library/dd757626.aspx
{
    return DllCall("Winmm.dll\timeEndPeriod", "UInt", uPeriod, "UInt")
}
=========================================================

Interesting Links about GetTickCount & timeGetTime
- What’s the difference between GetTickCount and timeGetTime?
- Bug in waitable timers?

Image
[AHK] 1.1.32.00 x64 Unicode | [WIN] 10 Pro (Version 2004) x64 | [GitHub] Profile
Donations are appreciated if I could help you
User avatar
Raccoon
Posts: 53
Joined: 26 Jul 2014, 16:15

Re: A_TickCount to use GetTickCount64 instead of GetTickCoun

24 Sep 2014, 06:16

Aye, I'm familiar with all of these.

AHK_L can check internally which is more appropriate to use for minimum support.

You seem to gloss over the fact that GetTimeCount is flawed in its 49.7 day limitation. (timeEndPeriod as well)

This scripting engine should strive to use the best available features at its disposal, without requiring lay users to learn "fancy DllCalls".
Last edited by Raccoon on 24 Sep 2014, 06:55, edited 1 time in total.
User avatar
Raccoon
Posts: 53
Joined: 26 Jul 2014, 16:15

Re: A_TickCount to use GetTickCount64 instead of GetTickCoun

24 Sep 2014, 06:41

Swaying off topic:

It doesn't appear that timeBeginPeriod()/timeEndPeriod() are necessary nor effect the resolution of either GetTickCount() or timeGetTime(). Changing the resolution from 1 to 100 or 1000 yields the same results.

Yes, GetTickCount() is based off the minimum resolution of the system clock, and timeGetTime() is based on the processor's timing. While timeGetTime has a lower resolution, it also sways a little bit +/- from real time as it's not based on a quartz crystal like GetTickCount is. Of course, the sway is negligible and impractical to worry about.

Here's a fun comparison script of the two functions.

Code: Select all

s:=""
Loop, 50
{
  gtc:=DllCall("GetTickCount"), tgt:=DllCall("Winmm\timeGetTime")
  s.=gtc " `t " tgt " `t " gtc-tgt "`n" 
  sleep 1
}
msgbox % s
ExitApp
User avatar
jNizM
Posts: 2665
Joined: 30 Sep 2013, 01:33
GitHub: jNizM
Contact:

Re: A_TickCount to use GetTickCount64 instead of GetTickCoun

24 Sep 2014, 07:10

Raccoon wrote:This scripting engine should strive to use the best available features at its disposal [...]
Thats true =)

OT
just fyi
Timers, Timer Resolution, and Development of Efficient Code
[AHK] 1.1.32.00 x64 Unicode | [WIN] 10 Pro (Version 2004) x64 | [GitHub] Profile
Donations are appreciated if I could help you
User avatar
Raccoon
Posts: 53
Joined: 26 Jul 2014, 16:15

Re: A_TickCount to use GetTickCount64 instead of GetTickCoun

24 Sep 2014, 12:37

Re:OT: One glaring typo in there seems to be "The default timer resolution on Windows 7 is 15.6 milliseconds (ms)." ... that's only true if your system clock is running at 64Hz, but some cheaper system clocks are wired at somewhere between 99Hz and 100Hz which is where Get/SetSystemTimeAdjust() comes in handy to both look up this resolution and tweak it if your system clock drifts too much from real time. A side effect of having a 100Hz system clock is your application timers [WM_TIMER] fire more rapidly (even in Windows 7).
User avatar
nnnik
Posts: 4479
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: A_TickCount to use GetTickCount64 instead of GetTickCoun

25 Sep 2014, 01:22

You do need to learn DllCall if you want extended functionality.
Recommends AHK Studio
User avatar
Raccoon
Posts: 53
Joined: 26 Jul 2014, 16:15

Re: A_TickCount to use GetTickCount64 instead of GetTickCoun

02 Oct 2014, 20:22

nnnik wrote:You do need to learn DllCall if you want extended functionality.
Which is why A_TickCount must be updated, since the average user doesn't learn DllCall... nor should they need to.

MSDN says that GetTickCount() is deprecated and should no longer be used. AHK should only use it for conditional backwards compatibility in builds that still support XP (if any).
User avatar
nnnik
Posts: 4479
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: A_TickCount to use GetTickCount64 instead of GetTickCoun

03 Oct 2014, 00:14

Most users like that will not care whether they use GetTickCount64 instead of GetTickCount.
Also it would break some old scripts so can only be applied to AHKv2 and would then break scripts between XP and newer Windows versions.
Recommends AHK Studio
User avatar
Raccoon
Posts: 53
Joined: 26 Jul 2014, 16:15

Re: A_TickCount to use GetTickCount64 instead of GetTickCoun

04 Oct 2014, 16:09

Challenging that a bug fix (the 49.7 day limitation) will break old scripts (that work around this bug) is a logical fallacy in software development.

Those old scripts will be updated accordingly, should any exist.
Bruttosozialprodukt
Posts: 463
Joined: 24 Jan 2014, 22:28

Re: A_TickCount to use GetTickCount64 instead of GetTickCoun

08 Dec 2014, 10:10

I'm on Raccoons side here, the fact that scripts running for 50 days would break is kind of alarming imo.
I for example put my PC into hibernate instead of shutting down most of the time.
lexikos
Posts: 7088
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: A_TickCount to use GetTickCount64 instead of GetTickCoun

09 Dec 2014, 03:25

If someone who actually cares (i.e. not me) were to make the change and do proper testing and benchmarking, I would consider integrating it.

AutoHotkey uses GetTickCount in quite a number of places internally, so some features other than A_TickCount might also be affected by the (exceedingly rare) limitation. Using GetTickCount64 while also supporting XP would require dynamic binding, which may increase code size and decrease performance (if all instances of GetTickCount were replaced; it is called very often).

Whether a script would break would depend on how the tick count was used. I suppose it would have to be used before and after the 49.7 day overflow occurred, so that end - start produces a negative number (or internally, a very large unsigned number). How severe the consequence of this breakage would be would obviously also depend on the script/usage.

I find it hard to believe there is any script which relies on the overflow occurring. The only practical use for detecting the overflow - that I can think of - would be to work around it.
User avatar
joedf
Posts: 7796
Joined: 29 Sep 2013, 17:08
Facebook: J0EDF
Google: +joedf
GitHub: joedf
Location: Canada
Contact:

Re: A_TickCount to use GetTickCount64 instead of GetTickCoun

09 Dec 2014, 09:08

IMO, it's not worth it. If you're going to a run a script for 50 days, get the system time (sync with the PC) or use DLLCall.
Bruttosozialprodukt
Posts: 463
Joined: 24 Jan 2014, 22:28

Re: A_TickCount to use GetTickCount64 instead of GetTickCoun

09 Dec 2014, 09:28

One simple check in the very beginning like f = (A_Is64Bit ? GetTickCount64 : GetTickCount); would probably do he job.
I don't think it would affect the performance in a noticeable way.
But I agree it's too much work to implement, as no one has been complaining about issues with this before.

The limitation should be mentioned in the documentation though.
User avatar
joedf
Posts: 7796
Joined: 29 Sep 2013, 17:08
Facebook: J0EDF
Google: +joedf
GitHub: joedf
Location: Canada
Contact:

Re: A_TickCount to use GetTickCount64 instead of GetTickCoun

09 Dec 2014, 11:28

Maybe a notice in the docs is not such a bad idea.
User avatar
jNizM
Posts: 2665
Joined: 30 Sep 2013, 01:33
GitHub: jNizM
Contact:

Re: A_TickCount to use GetTickCount64 instead of GetTickCoun

10 Dec 2014, 01:47

dont forget the right end-type in ahk

Tick := ((A_Is64bitOS) ? DllCall("Kernel32.dll\GetTickCount64", "UInt64") : DllCall("Kernel32.dll\GetTickCount", "UInt"))

Code: Select all

var1 := A_TickCount
var2 := DllCall("kernel32.dll\GetTickCount", "UInt")
var3 := DllCall("kernel32.dll\GetTickCount64", "UInt64")
var4 := DllCall("winmm.dll\timeGetTime", "UInt")

MsgBox, % var1 "`n" var2 "`n" var3 "`n" var4 "`n"
[AHK] 1.1.32.00 x64 Unicode | [WIN] 10 Pro (Version 2004) x64 | [GitHub] Profile
Donations are appreciated if I could help you
Bruttosozialprodukt
Posts: 463
Joined: 24 Jan 2014, 22:28

Re: A_TickCount to use GetTickCount64 instead of GetTickCoun

10 Dec 2014, 09:29

My idea was c++ code and assumed that A_Is64bitOS was supposed to store an exact copy of one function in f.
In theory it could be used like this:

Code: Select all

#include <windows.h>
f = (A_Is64bitOS ? GetTickCount64 : GetTickCount);

f(); //is the same as GetTickCount64() on a x64 OS and GetTickCount() on a x86 OS
User avatar
nnnik
Posts: 4479
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: A_TickCount to use GetTickCount64 instead of GetTickCoun

10 Dec 2014, 09:46

jNizM wrote:dont forget the right end-type in ahk

Tick := ((A_Is64bitOS) ? DllCall("Kernel32.dll\GetTickCount64", "UInt64") : DllCall("Kernel32.dll\GetTickCount", "UInt"))

Code: Select all

var1 := A_TickCount
var2 := DllCall("kernel32.dll\GetTickCount", "UInt")
var3 := DllCall("kernel32.dll\GetTickCount64", "UInt64")
var4 := DllCall("winmm.dll\timeGetTime", "UInt")

MsgBox, % var1 "`n" var2 "`n" var3 "`n" var4 "`n"
I agree that this is a necessity in the second example.
However it is not necessity in the first example since you could just use the default type which is pointer and 64 bits on a 64 bit OS and 32 bits on a 32 bit OS.
Recommends AHK Studio

Return to “Wish List”

Who is online

Users browsing this forum: No registered users and 2 guests