python - now - ¿Qué tan preciso es el tiempo de pitón.sleep()?
time python example (7)
¿Por qué no lo averiguas?
from datetime import datetime
import time
def check_sleep(amount):
start = datetime.now()
time.sleep(amount)
end = datetime.now()
delta = end-start
return delta.seconds + delta.microseconds/1000000.
error = sum(abs(check_sleep(0.050)-0.050) for i in xrange(100))*10
print "Average error is %0.2fms" % error
Para el registro, obtengo un error de 0.1ms en mi HTPC y 2ms en mi computadora portátil, ambas máquinas linux.
Puedo darle números de coma flotante, como
time.sleep(0.5)
pero que tan exacto es? Si lo doy
time.sleep(0.05)
¿Dormirá realmente alrededor de 50 ms?
Aquí está mi seguimiento de la respuesta de Wilbert: lo mismo para Mac OS X Yosemite, ya que no se ha mencionado mucho todavía.
Parece que muchas veces duerme aproximadamente 1,25 veces el tiempo que usted solicita y, a veces, duerme entre 1 y 1,25 veces el tiempo que solicita. Casi nunca (~ dos de cada 1000 muestras) duerme significativamente más de 1,25 veces el tiempo que usted solicita.
Además (no se muestra explícitamente), la relación 1.25 parece mantenerse bastante bien hasta que llegas por debajo de 0.2 ms, después de lo cual comienza a ser un poco borroso. Además, el tiempo real parece establecerse en aproximadamente 5 ms más de lo que solicitas luego de que la cantidad de tiempo solicitada supera los 20 ms.
Nuevamente, parece ser una implementación completamente diferente de sleep()
en OS X que en Windows o cualquiera que sea el kernel de Linux que Wilbert estaba usando.
De la documentation :
Por otro lado, la precisión de
time()
ysleep()
es mejor que sus equivalentes de Unix: los tiempos se expresan como números flotantes,time()
devuelve el tiempo más preciso disponible (usando Unixgettimeofday
donde esté disponible) ysleep()
aceptará un tiempo con una fracción diferente de cero (laselect
Unix se usa para implementar esto, donde esté disponible).
Y más específicamente wrt sleep()
:
Suspender la ejecución por el número de segundos especificado. El argumento puede ser un número de coma flotante para indicar un tiempo de suspensión más preciso. El tiempo de suspensión real puede ser menor que el solicitado porque cualquier señal atrapada terminará la
sleep()
después de la ejecución de la rutina de captura de esa señal. Además, el tiempo de suspensión puede ser más largo que el solicitado por una cantidad arbitraria debido a la programación de otra actividad en el sistema.
La gente tiene razón sobre las diferencias entre los sistemas operativos y los kernels, pero no veo granularidad en Ubuntu y veo una granularidad de 1 ms en MS7. Sugiriendo una implementación diferente de time.sleep, no solo una tasa de ticks diferente. Una inspección más detallada sugiere una granularidad de 1μs en Ubuntu, por cierto, pero eso se debe a la función time.time que uso para medir la precisión.
La precisión de la función time.sleep depende de la precisión del sueño de su SO subyacente. Para sistemas operativos que no son en tiempo real como Windows, el intervalo más pequeño para el que puede dormir es de aproximadamente 10 a 13 ms. He visto durmientes precisos dentro de varios milisegundos de ese momento cuando están por encima del mínimo de 10-13ms.
Actualización: como se menciona en los documentos que se encuentran a continuación, es común dormir en un ciclo que asegurará volver a dormirse si lo despierta temprano.
También debo mencionar que si está ejecutando Ubuntu, puede probar un kernel pseudo en tiempo real (con el conjunto de parches RT_PREEMPT) instalando el paquete rt kernel (al menos en Ubuntu 10.04 LTS).
EDITAR: la corrección de kernels Linux no en tiempo real tiene un intervalo mínimo de sueño mucho más cercano a 1 ms que a 10 ms, pero varía de manera no determinista.
Realmente no se puede garantizar nada sobre el sueño (), excepto que al menos hará un mejor esfuerzo para dormir todo el tiempo que lo indique (las señales pueden matar su sueño antes de que se acabe el tiempo, y muchas más cosas pueden hacer que funcione largo).
Por supuesto, el mínimo que puede obtener en un sistema operativo de escritorio estándar va a ser de alrededor de 16 ms (granularidad del temporizador más tiempo para el cambio de contexto), pero es probable que el% de desviación del argumento proporcionado sea significativo cuando lo intente. dormir por 10s de milisegundos.
Las señales, otros hilos que contienen el GIL, la programación del kernel, la velocidad del procesador, etc. pueden causar estragos en la duración del hilo / proceso que realmente duerme.
Una pequeña corrección, varias personas mencionan que el sueño puede terminar temprano por una señal. En los 3.6 documentos dice:
Modificado en la versión 3.5: la función ahora duerme al menos segundos incluso si el sueño se interrumpe por una señal, excepto si el manejador de señal genera una excepción (ver PEP 475 para la justificación).