Jump to content

Recommended Posts

Posted (edited)

I did a test..

First I TimerDiff't sleep(1000) 2 times

result:

1: 1003.58872426523

2: 1008.31055343626

thats 3 millie seconds wrong..

Now I made my own sleep :)

I did 2 tests with _Sleep(1000) and got the following results:

1: 1000.01117460459

2: 1000.01340952551

Very accurate!

just to let people now that sleep is not so accurate... because when someone is making something wich needs very accurate sleeping my code could be better :P

here are the tests:

$11 = _Example1()
$12 = _Example1()
$21 = _Example2()
$22 = _Example2()
msgbox ( 32, 'sleeping results', 'the results for normal sleep are:'&@CRLF&'1) '&$11&@CRLF&'2) '&$12&@CRLF&@CRLF&'The results for my _Sleep are:'&@CRLF&'1) '&$21&@CRLF&'2) '&$22)
ClipPut($11&@CRLF&$12&@CRLF&$21&@CRLF&$22)
Func _Example1() ;normal sleep
$Timer = TimerInit()
sleep(1000)
$tmp = TimerDiff($timer)
return $tmp
EndFunc

Func _Example2() ;my _Sleep
$Timer = TimerInit()
_Sleep(1000)
$tmp = TimerDiff($timer)
return $tmp
EndFunc

Func _Sleep($sTime)
    $timer=TimerInit()
    Do
        $tmp = TimerDiff($timer)
    Until $tmp >= $sTime
EndFunc
Edited by ludocus
Posted (edited)

yeh thats true...

The standard Sleep function isn't as accurate because it just rests with a very low CPU priority/usage... so there is a timelaps between the moment it says "time is over" and the moment where the cpu gets available for this info...

I guess that if you start CPU Burn at the same time as the standard Sleep the standard one will be much more accurate.

Edited by JavaCupiX
Posted (edited)

I found that directly calling the Sleep function in kernel32.dll was more accurate than the built in sleep:

$timer=TimerInit()
Sleep(2500)
ConsoleWrite(TimerDiff($timer)&" milliseconds"&@CRLF)

$dll=DllOpen("kernel32.dll")
$timer=TimerInit()
DllCall($dll,"none","Sleep","dword",2500)
ConsoleWrite(TimerDiff($timer)&" milliseconds"&@CRLF)

:)

Edited by monoceres

Broken link? PM me and I'll send you the file!

Posted

The standard Sleep function isn't as accurate because it just rests with a very low CPU priority/usage... so there is a timelaps between the moment it says "time is over" and the moment where the cpu gets available for this info...

I guess that if you start CPU Burn at the same time as the standard Sleep the standard one will be much more accurate.

Using that theory, some tests:

AdlibEnable("burn", 1)

$timer = TimerInit()
Sleep (1000)
$diff = TimerDiff($timer)
MsgBox(0, "with burn - autoit "&@AutoItVersion, $diff)
ClipPut($diff)

Func burn()
    $blah = TimerDiff($timer)
EndFuncoÝ÷ Û}µÛY¨²ÖÚrH+¢éݦº ­©¬rZ,yß|ï½¼×Nºß5ãß

1000.01080577208

1000.0109460981

1000.00941788088

1000.01248233396

1000.01149270138

Average: ~1000.011 (+0.011 difference)

So the least accurate is the built-in sleep function with cpu burning, at a difference of -11.644.

The most accurate is Ludocus' sleep function at a difference of only +0.011.

The cake is a lie.www.theguy0000.com is currentlyUP images.theguy0000.com is currentlyUP all other *.theguy0000.com sites are DOWN

  • Moderators
Posted

Having said that ... and if accuracy is very important, I'd simply adjust my sleep milliseconds accordingly to get as accurate as I could, versus sacrificing cpu usage.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Posted

That doesn't really work either:

$xTra = 9.708;thats what came out Theguy000's post...
ClipPut('')
For $k=1 to 2
For $i = 1 to 10
$timer = TimerInit()
Call('_Sleep'&$k, 1000)
$diff = TimerDiff($timer)
ClipPut(ClipGet()&@CRLF&';'&$diff)
Next
Next

;and the following turned out;
;#1:
;1008.4600137727
;1015.39832576487
;1018.59677696467
;1009.74397584051
;1008.8365979475
;1014.93234475331
;1031.15982617903
;1031.04528648194
;1019.196015136
;1017.63324668359
;#2:
;998.316545817974
;996.804342451345
;989.328811343341
;996.950171041292
;998.00002514286
;1015.03738603649
;1015.21897336114
;990.587351185695
;997.588240963586
;999.04820305374

Func _Sleep1($sTime)
    Sleep($sTime+$xTra)
EndFunc

Func _Sleep2($sTime)
    Sleep($sTime-$xTra)
EndFunc
Posted

As far as using up CPU time, could one not use a hybrid method? Use the normal sleep to bring the delay within say 20ms then use the CPU intensive polling loop.

Func _Sleep($sTime)
    $timer=TimerInit()
    Sleep($sTime - 20)
    Do
        $tmp = TimerDiff($timer)
    Until $tmp >= $sTime
EndFunc

---------------------------

sleeping results

---------------------------

the results for normal sleep are:

1) 990.113547950927

2) 999.914793639974

The results for my _Sleep are:

1) 1000.02486349522

2) 1000.47743498126

---------------------------

OK

---------------------------

---------------------------

sleeping results

---------------------------

the results for normal sleep are:

1) 988.238728665235

2) 1000.61655880845

The results for hybrid _Sleep are:

1) 1000.03268571844

2) 1000.23801907784

---------------------------

OK

---------------------------

  • 2 months later...
Posted

I found this interesting topic in someone's signature. The following script tries to correction the difference from the fastest method. It does barely anything.

Dim $mTargetWait = 100
Dim $mResult[10]
Dim $mAvDiff = 0

;; Make some test results
For $i = 0 to UBound($mResult)-1
    $lTimer = TimerInit()
    _Sleep($mTargetWait)
    $mResult[$i] = TimerDiff($lTimer)
Next

;; Calculate average difference
$lTotal = 0
For $i = 0 to UBound($mResult)-1
    $lTotal += $mResult[$i]-$mTargetWait
Next
$mAvDiff = $lTotal/UBound($mResult)
_Print($mResult, "Average difference: " & $mAvDiff, "Sleep without correction")

;; Make some test results now with correction
For $i = 0 to UBound($mResult)-1
    $lTimer = TimerInit()
    _Sleep($mTargetWait)
    $mResult[$i] = TimerDiff($lTimer)
Next

;; Calculate average difference with correction
$lTotal = 0
For $i = 0 to UBound($mResult)-1
    $lTotal += $mResult[$i]-$mTargetWait
Next
$mAvDiff = $lTotal/UBound($mResult)
_Print($mResult, "Average difference: " & $mAvDiff, "Sleep WITH correction")


;; Trying to keep _Sleep as short as possible, to not stress the interpreter
Func _Sleep($B)
    $b -= $mAvDiff
    $a = TimerInit()
    Do
    Until TimerDiff($a) >= $b
EndFunc

;; Custom print function, that makes no sense at all lulz
Func _Print($pArray, $pText, $pTitle)
    $lReturn = ""
    For $i = 0 to UBound($pArray)-1
        $lReturn &= "[" & $i & "] = " & $pArray[$i] & @CRLF
    Next
    $lReturn &= @CRLF & @CRLF & $pText
    MsgBox(0, $pTitle, $lReturn)
EndFunc
Posted (edited)

Func _Sleep($sTime)
    $timer = TimerInit()

    Do
        Sleep(1)
        $tmp = TimerDiff($timer)
    Until $tmp > ($sTime * .99); .99 works well for anything over 700ms, .95 works well for anything over 65ms
        
    While $tmp < $sTime
        $tmp = TimerDiff($timer)
    WEnd
EndFunc  ;==>_Sleep

Edited by Vakari
Posted

TimerInit and TimerDiff also take some time to calculate.

Yes, and the interpreter also takes some time to do a loop. It is all based on how much your computer is being stressed. Your best bet if you want a super accurate sleep is to absolutely kill all process and services, and run your AutoIt script that uses a dynamically corrected Sleep. You could have it do 10 loops of trying just to get it almost right.

This could potentially lead to a sleep with a variation of 0.000001s and less.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...