SetBatchLines -1
;初始化一下函数,避免第一次计时不精准
QPC()
Sleep1()
Sleep2()
Sleep3()
;------------------------------
F2::
休眠次数:=50
T1:=QPC()
loop % 休眠次数{
Sleep1(0.8) ;休眠1ms
}
经过时间:=QPC()-T1
MsgBox % "休眠" 休眠次数 "次`n经过时间: " 经过时间 "`n平均耗时: " 经过时间/休眠次数
return
;Sleep3固定经过时间示例
F3::
固定时间:=100 ;100ms
T1:=QPC()
Sleep3(固定时间+T1)
经过时间:=QPC()-T1
MsgBox % "经过时间: " 经过时间
return
;Sleep3固定每次循环时间示例
F4::
循环次数:=500
固定时间:=0.1 ;0.1ms
T1:=QPC()
loop % 循环次数{
Sleep3(固定时间*A_Index+T1)
}
经过时间:=QPC()-T1
MsgBox % "循环" 循环次数 "次`n经过时间: " 经过时间 "`n平均耗时: " 经过时间/循环次数
return
QPC() {
static Freq,MulDivProc,init
if (!init)
{
MulDivProc:=DllCall("GetProcAddress", "Ptr", DllCall("LoadLibrary", "Str", "Kernel32", "Ptr"), "AStr", "QueryPerformanceCounter", "Ptr")
DllCall("QueryPerformanceFrequency", "Int64P", Freq)
init:=1
}
DllCall(MulDivProc, "Int64P", Count1)
return Count1/Freq*1000
}
Sleep1(ms=0.8)
{
static init,socket,MulDivProc,timeBeginPeriod,timeEndPeriod,NtSetTimerResolution
if (!init)
{
MulDivProc := DllCall("GetProcAddress", "Ptr", DllCall("LoadLibrary", "Str", "Ws2_32", "Ptr"), "AStr", "select", "Ptr")
timeBeginPeriod := DllCall("GetProcAddress", "Ptr", DllCall("LoadLibrary", "Str", "Winmm", "Ptr"), "AStr", "timeBeginPeriod", "Ptr")
timeEndPeriod := DllCall("GetProcAddress", "Ptr", DllCall("LoadLibrary", "Str", "Winmm", "Ptr"), "AStr", "timeEndPeriod", "Ptr")
NtSetTimerResolution := DllCall("GetProcAddress", "Ptr", DllCall("LoadLibrary", "Str", "NTDLL", "Ptr"), "AStr", "NtSetTimerResolution", "Ptr") ;0.5ms
VarSetCapacity(wsaData, 408)
DllCall("Ws2_32\WSAStartup", "ushort",2|(2<<8), "Ptr", &wsaData)
socket:=DllCall("Ws2_32\socket", "int", 2, "int", 1, "int", 0)
init:=1
}
VarSetCapacity(rfds, A_PtrSize*(64+1), 0)
NumPut(socket, rfds, A_PtrSize, "Ptr"), NumPut(1, rfds, "int")
VarSetCapacity(Hints, 8, 0)
NumPut(tv_sec:=0, Hints, 0, "Int")
NumPut(tv_usec:=Round(ms*1000), Hints, 4, "Int")
DllCall(timeBeginPeriod, "UInt", 1)
DllCall(MulDivProc, "Int",1, "Ptr",&rfds, "Ptr",0, "Ptr",0, "Ptr",&Hints)
DllCall(timeEndPeriod, "UInt", 1)
; DllCall(NtSetTimerResolution, "UInt", 5000, "UInt", 1, "UInt*", TimerResolutionActual) ;设置计时器分辨率为0.5ms
; DllCall(MulDivProc, "Int",1, "Ptr",&rfds, "Ptr",0, "Ptr",0, "Ptr",&Hints)
; DllCall(NtSetTimerResolution, "UInt", 5000, "UInt", 0, "UInt*", TimerResolutionActual) ;还原默认计时器分辨率
}
Sleep2(time=1){
static init,timeBeginPeriod,timeEndPeriod
if (!init)
{
timeBeginPeriod := DllCall("GetProcAddress", "Ptr", DllCall("LoadLibrary", "Str", "Winmm", "Ptr"), "AStr", "timeBeginPeriod", "Ptr")
timeEndPeriod := DllCall("GetProcAddress", "Ptr", DllCall("LoadLibrary", "Str", "Winmm", "Ptr"), "AStr", "timeEndPeriod", "Ptr")
init:=1
}
time:=Round(time)
if (time>15)
DllCall("Sleep", "UInt", time) ; 只支持整数休眠
else{
DllCall(timeBeginPeriod, "UInt", time)
DllCall("Sleep", "UInt", time) ; 只支持整数休眠
DllCall(timeEndPeriod, "UInt", time)
}
}
Sleep3(EndTime=0) ;此方式可能会吃一点CPU
{
static Freq,MulDivProc,init,timeBeginPeriod,timeEndPeriod
if (!init)
{
MulDivProc:=DllCall("GetProcAddress", "Ptr", DllCall("LoadLibrary", "Str", "Kernel32", "Ptr"), "AStr", "QueryPerformanceCounter", "Ptr")
timeBeginPeriod := DllCall("GetProcAddress", "Ptr", DllCall("LoadLibrary", "Str", "Winmm", "Ptr"), "AStr", "timeBeginPeriod", "Ptr")
timeEndPeriod := DllCall("GetProcAddress", "Ptr", DllCall("LoadLibrary", "Str", "Winmm", "Ptr"), "AStr", "timeEndPeriod", "Ptr")
DllCall("QueryPerformanceFrequency", "Int64P", Freq)
init:=1
}
EndTime := EndTime*Freq/1000
DllCall("QueryPerformanceCounter", "Int64*", t_current)
休眠时间:=(EndTime-t_current)/Freq*1000
休眠时间:=Floor(休眠时间-1) ;最后1ms用轮循方式等待
if(休眠时间>=1)
{
DllCall(timeBeginPeriod, "UInt", 休眠时间)
DllCall("Sleep", "UInt", 休眠时间)
DllCall(timeEndPeriod, "UInt", 休眠时间)
DllCall("QueryPerformanceCounter", "Int64*", t_current)
}
while (t_current < EndTime)
DllCall("QueryPerformanceCounter", "Int64*", t_current)
}
暂无讨论,说说你的看法吧