Python sehr genaue Zeit messen?

2 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

Meine Ansatz wäre vermutlich sowas wie

from datetime import datetime as dt

waittime = 50 #x microseconds

def Micros():
    return dt.now().microsecond
    
release = Micros() + waittime

print(Micros())

while 1:
    if Micros()<waittime and release>=1000000:
        release-=1000000
    if Micros() >= release:
        break
    
print(Micros())

Da ein Funktionsaufruf in Python aber immer seine Zeit dauert und du eine geringe Toleranz haben möchtest, könnte es ggf. besser sein, Micros() durch dt.now().microsecond zu ersetzen und auf die Funktion zu verzichten. Also dann so, wenn auch code-technisch eher unschön

from datetime import datetime as dt

waittime = 50 #x microseconds

release = dt.now().microsecond + waittime

print(dt.now().microsecond)

while 1:
    if dt.now().microsecond<waittime and release>=1000000:
        release-=1000000
    if dt.now().microsecond >= release:
        break
    
print(dt.now().microsecond)
EchterNaivling 
Fragesteller
 18.07.2022, 16:20

Was macht dieser Code jetzt?
Wofür brauche ich "waittime"?

0
GuteAntwort2021  18.07.2022, 17:35
@EchterNaivling

waittime -> Zeit die gewartet werden soll, was sogar noch als Kommentar dahinter steht.

X Microseconds, also die Wartezeit in Mikrosekunden. Eine Microsekunde ist 1/1.000.000 Sekunde. 50 Microsekunden entsprechen also z. B. 0,05 Millisekunden.

Ich persönliche würde den Code in einer Methode hinterlegen, also zum Beispiel so:

from datetime import datetime as dt


def WaitForX(t): #t microseconds
    release = dt.now().microsecond + t
    #Handle when we hit a new second
    if release >= 1000000:
        release -= 1000000
        while dt.now().microsecond > t:
            continue
    while 1:
        if dt.now().microsecond >= release:
            break


WaitForX(250)

Der Funktionsaufruf WaitForX(250) würde also dafür sorgen, dass das Programm an der Stelle rund 0,00025 Sekunden wartet (250 / 1.000.000 von einer Sekunde).

Hier ein kleiner Testlauf um zu zeigen, wie relativ nah die Funktion drankommt:

from datetime import datetime as dt


def WaitForX(t): #t microseconds
    release = dt.now().microsecond + t
    #Handle when we hit a new second
    if release >= 1000000:
        release -= 1000000
        while dt.now().microsecond > t:
            continue
    while 1:
        if dt.now().microsecond >= release:
            break


n = 5000
timecount = 0


for i in range(n):
    start = dt.now().microsecond
    WaitForX(250)
    end = dt.now().microsecond
    if end < start:
        timecount += (1000000 - start + end)
    else:
        timecount += end-start
    
print("Average waittime out of " + str(n) + " setups was " + str(timecount/n) + " microseconds.")
1
GuteAntwort2021  18.07.2022, 18:02
@GuteAntwort2021

Allerdings finde ich

time.sleep(seconds/1000000.0)

jetzt auch nicht so super ungenau. Musst du selbst entscheiden, welches dir angenehmer erscheint.

1

Bevor Du weitermachst, lies bitte erstmal die Manpage zu time:

man 7 time

Und schau Dir mal /proc/timer_list an, ob Du etwas mit ausreichend kleiner Granularität zur Verfügung hast.