Python 中的高精度时钟
- 2025-02-27 09:08:00
- admin 原创
- 24
问题描述:
有没有办法在 Python 中以高精度测量时间 --- 比一秒更精确?我怀疑是否有跨平台的方法可以做到这一点;我对 Unix 上的高精度时间很感兴趣,特别是在 Sun SPARC 机器上运行的 Solaris。
timeit似乎能够进行高精度的时间测量,但我更愿意直接访问时间值,而不是测量代码片段所花费的时间。
解决方案 1:
标准time.time()
函数提供亚秒级精度,但该精度因平台而异。对于 Linux 和 Mac,精度为+-
1 微秒或 0.001 毫秒。+-
由于进程中断导致时钟实现问题,Windows 上的 Python(Python 版本低于 3.7)使用 16 毫秒精度。timeit
如果您正在测量执行时间,该模块可以提供更高的分辨率。
>>> import time
>>> time.time() #return seconds from epoch
1261367718.971009
Python 3.7 为time
模块引入了新功能,可以为更长的时间段提供更高的分辨率:
>>> import time
>>> time.time_ns()
1530228533161016309
>>> time.time_ns() / (10 ** 9) # convert to floating-point seconds
1530228544.0792289
解决方案 2:
如果选择 Python 3,则有两个选择:
time.perf_counter
它始终使用平台上最准确的时钟。它确实包括进程之外所花费的时间。time.process_time
返回 CPU 时间。它不包括进程之外所花费的时间。
两者的区别可以通过以下方式展示:
from time import (
process_time,
perf_counter,
sleep,
)
print(process_time())
sleep(1)
print(process_time())
print(perf_counter())
sleep(1)
print(perf_counter())
输出:
0.03125
0.03125
2.560001310720671e-07
1.0005455362793145
解决方案 3:
David 的帖子试图显示 Windows 上的时钟分辨率。他的输出让我感到困惑,所以我写了一些代码来显示time.time()
我的 Windows 8 x64 笔记本电脑上的分辨率为 1 毫秒:
# measure the smallest time delta by spinning until the time changes
def measure():
t0 = time.time()
t1 = t0
while t1 == t0:
t1 = time.time()
return (t0, t1, t1-t0)
samples = [measure() for i in range(10)]
for s in samples:
print s
输出:
(1390455900.085, 1390455900.086, 0.0009999275207519531)
(1390455900.086, 1390455900.087, 0.0009999275207519531)
(1390455900.087, 1390455900.088, 0.0010001659393310547)
(1390455900.088, 1390455900.089, 0.0009999275207519531)
(1390455900.089, 1390455900.09, 0.0009999275207519531)
(1390455900.09, 1390455900.091, 0.0010001659393310547)
(1390455900.091, 1390455900.092, 0.0009999275207519531)
(1390455900.092, 1390455900.093, 0.0009999275207519531)
(1390455900.093, 1390455900.094, 0.0010001659393310547)
(1390455900.094, 1390455900.095, 0.0009999275207519531)
还有一种方法是对 1000 个样本的增量进行平均:
reduce( lambda a,b:a+b, [measure()[2] for i in range(1000)], 0.0) / 1000.0
连续两次运行的输出为:
0.001
0.0010009999275207519
因此time.time()
,我的 Windows 8 x64 的分辨率为 1 毫秒。
类似的运行time.clock()
返回 0.4 微秒的分辨率:
def measure_clock():
t0 = time.clock()
t1 = time.clock()
while t1 == t0:
t1 = time.clock()
return (t0, t1, t1-t0)
reduce( lambda a,b:a+b, [measure_clock()[2] for i in range(1000000)] )/1000000.0
返回:
4.3571334791658954e-07
哪个是〜0.4e-06
有趣的是time.clock()
,它返回自该方法首次调用以来的时间,因此如果您想要微秒分辨率的挂钟时间,您可以执行以下操作:
class HighPrecisionWallTime():
def __init__(self,):
self._wall_time_0 = time.time()
self._clock_0 = time.clock()
def sample(self,):
dc = time.clock()-self._clock_0
return self._wall_time_0 + dc
(一段时间后可能会出现偏差,但你可以偶尔纠正一下,例如dc > 3600
每小时纠正一次)
解决方案 4:
Python 尽力使用适合您平台的最精确的时间函数来实现time.time()
:
/* Implement floattime() for various platforms */
static double
floattime(void)
{
/* There are three ways to get the time:
(1) gettimeofday() -- resolution in microseconds
(2) ftime() -- resolution in milliseconds
(3) time() -- resolution in seconds
In all cases the return value is a float in seconds.
Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may
fail, so we fall back on ftime() or time().
Note: clock resolution does not imply clock accuracy! */
#ifdef HAVE_GETTIMEOFDAY
{
struct timeval t;
#ifdef GETTIMEOFDAY_NO_TZ
if (gettimeofday(&t) == 0)
return (double)t.tv_sec + t.tv_usec*0.000001;
#else /* !GETTIMEOFDAY_NO_TZ */
if (gettimeofday(&t, (struct timezone *)NULL) == 0)
return (double)t.tv_sec + t.tv_usec*0.000001;
#endif /* !GETTIMEOFDAY_NO_TZ */
}
#endif /* !HAVE_GETTIMEOFDAY */
{
#if defined(HAVE_FTIME)
struct timeb t;
ftime(&t);
return (double)t.time + (double)t.millitm * (double)0.001;
#else /* !HAVE_FTIME */
time_t secs;
time(&secs);
return (double)secs;
#endif /* !HAVE_FTIME */
}
}
(来自http://svn.python.org/view/python/trunk/Modules/timemodule.c?revision=81756&view=markup)
解决方案 5:
您还可以使用 time.clock() 它在 Unix 上计算进程所用的时间,在 Windows 上计算自第一次调用以来的时间。它比 time.time() 更精确。
这是衡量性能的常用函数。
只需拨打电话
import time
t_ = time.clock()
#Your code here
print 'Time in function', time.clock() - t_
编辑:哎呀,我错过了这个问题,因为你想知道确切的时间,而不是花费的时间......
解决方案 6:
Python 3.7 引入了 6 个具有纳秒分辨率的新时间函数,例如,time.time()
您可以使用time.time_ns()
来避免浮点不精确的问题:
import time
print(time.time())
# 1522915698.3436284
print(time.time_ns())
# 1522915698343660458
PEP 564中描述了这 6 个函数:
time.clock_gettime_ns(clock_id)
time.clock_settime_ns(clock_id, time:int)
time.monotonic_ns()
time.perf_counter_ns()
time.process_time_ns()
time.time_ns()
这些函数与没有 _ns 后缀的版本类似,但以 Python int 形式返回纳秒数。
解决方案 7:
time.clock()
在 Windows 上有 13 个小数点,但在 Linux 上只有 2 个小数点。time.time()
在 Linux 上有 17 个小数点,在 Windows 上有 16 个小数点,但实际精度不同。
我不同意time.clock()
应该在 Unix/Linux 上用于基准测试的文档。它不够精确,因此使用什么计时器取决于操作系统。
在 Linux 上,时间分辨率较高time.time()
:
>>> time.time(), time.time()
(1281384913.4374139, 1281384913.4374161)
然而在 Windows 上,时间函数似乎使用最后调用的号码:
>>> time.time()-int(time.time()), time.time()-int(time.time()), time.time()-time.time()
(0.9570000171661377, 0.9570000171661377, 0.0)
即使我在 Windows 中的不同行上写入调用,它仍然返回相同的值,因此实际精度较低。
import platform, platform.system()
因此,在进行严肃的测量时,必须进行平台检查( ),以确定是否使用time.clock()
或time.time()
。
(在 Windows 7 和 Ubuntu 9.10 上测试,使用 Python 2.6 和 3.1)
解决方案 8:
最初的问题专门针对 Unix,但多个答案涉及 Windows,因此 Windows 上的信息具有误导性。Windows 上的默认计时器分辨率为 15.6ms,您可以在此处验证。
使用来自 cod3monk3y 的稍作修改的脚本,我可以显示 Windows 计时器分辨率默认为 ~15 毫秒。我正在使用此处提供的工具来修改分辨率。
脚本:
import time
# measure the smallest time delta by spinning until the time changes
def measure():
t0 = time.time()
t1 = t0
while t1 == t0:
t1 = time.time()
return t1-t0
samples = [measure() for i in range(30)]
for s in samples:
print(f'time delta: {s:.4f} seconds')
这些结果是在运行 python 3.7 64 位的 Windows 10 Pro 64 位上收集的。
解决方案 9:
用于 Python 中的高精度计时
快速摘要
其中time.monotonic_ns()
,,time.perf_counter_ns()
和time.time_ns()
,**在Linux和Windows上都仅time.perf_counter_ns()
具有亚微秒的精度。
许多人可能不理解分辨率、精度和准确度之间的区别,并可能错误地认为精确计时比实际情况更容易、更容易实现。请记住,在软件计时的背景下:
分辨率= 单位可以表示的最小时间差。例如:1 纳秒。
精度= 测量的可重复性。这是您可以重复测量的最小时间差,通常比分辨率大得多。例如:Linux 上通常为 0.070 微秒(70 纳秒),Windows 上则高达 16000 微秒(16 毫秒),或差约 23 万倍。
准确度= 测量值与真实值的接近程度。这与硬件时钟的石英晶体(或等效 RC、陶瓷或 PLL)振荡器的准确度以及校准程度有关。我们在这里不担心这一点。
使用time_monotonic_ns__get_precision.py
下面的程序,以下是我在 Dell Precision 5570 Pentium i9(Linux)和 i7(Windows 11)高端 20 线程笔记本电脑上测试的结果。您的结果将根据您的硬件和操作系统而有所不同:
-------------------------------------------------------------------------------
1. time.monotonic_ns()
-------------------------------------------------------------------------------
Resolution Precision
---------- ---------
Linux: 1 ns 0.070 us +/- 0.118 us (70 ns +/- 118 ns)
Windows: 1 ns 16000.000 us +/- 486.897 us (16 ms +/- 0.487 ms)
-------------------------------------------------------------------------------
2. time.perf_counter_ns()
-------------------------------------------------------------------------------
Resolution Precision
---------- ---------
Linux: 1 ns 0.069 us +/- 0.070 us ( 69 ns +/- 70 ns)
Windows: 1 ns 0.100 us +/- 0.021 us (100 ns +/- 21 ns)
-------------------------------------------------------------------------------
3. time.time_ns()
-------------------------------------------------------------------------------
Resolution Precision
---------- ---------
Linux: 1 ns 0.074 us +/- 0.226 us (74 ns +/- 226 ns)
Windows: 1 ns 10134.354 us +/- 5201.053 us (10.134 ms +/- 5.201 ms)
请注意,尽管所有 3 个函数都具有 1 纳秒的分辨率,但**在 Linux 和 Windows 上都只time.perf_counter_ns()
具有亚微秒的精度。其他两个函数仅在 Linux 上具有亚微秒的精度,但在 Windows 上却很糟糕(精度低)。
细节
Python 3.7 或更高版本
如果使用 Python 3.7 或更高版本,请使用此处的现代跨平台time
模块函数,如time.monotonic_ns()
、time.perf_counter_ns()
和time.time_ns()
:https://docs.python.org/3/library/time.html#time.monotonic_ns。
import time
# For Unix, Linux, Windows, etc.
time_ns = time.monotonic_ns() # note: unspecified epoch
time_ns = time.perf_counter_ns() # **best precision**
time_ns = time.time_ns() # known epoch
# Unix or Linux only
time_ns = time.clock_gettime_ns()
# etc. etc. There are others. See the link above.
另请参阅我 2016 年的另一个回答中的这条注释:如何在 Python 中获取毫秒和微秒分辨率的时间戳?:
您也可以
time.clock_gettime_ns()
在 Unix 或 Linux 系统上尝试。根据其名称,它似乎调用了底层C 函数,我在 C 函数(此处的答案)和 C Unix/Linux 库(此处)中clock_gettime()
使用该函数: timinglib.c。nanos()
作为快速测试,您可以运行以下命令来了解特定硬件和操作系统的最低分辨率。我已经在 Linux 和 Windows 上测试并运行了此操作:
来自我的eRCaGuy_hello_world repo 的python/time_monotonic_ns__get_precision.py:
#!/usr/bin/env python3
import os
import pandas as pd
import time
SAMPLE_SIZE_DEFAULT = 20000
# For cases where Windows may have really crappy 16ms precision, we need a
# significantly larger sample size.
SAMPLE_SIZE_MIN_FOR_WINDOWS = 20000000
DEBUG = False # Set to True to enable debug prints
def debug_print(*args, **kwargs):
if DEBUG:
print(*args, **kwargs)
def print_bar():
debug_print("="*56, "
")
def process_timestamps(timestamps_ns, output_stats_header_str):
"""
Process the timestamps list to determine the time precision of the system.
"""
# Create a pandas DataFrame for efficient analysis of large datasets
df = pd.DataFrame({"timestamp_ns": timestamps_ns}, dtype='int64')
debug_print(f"df original:
{df}")
print_bar()
# Remove duplicate timestamps. On Linux, there won't be any, because it has
# sub-microsecond precision, but on Windows, the dataset may be mostly
# duplicates because repeated calls to `time.monotonic_ns()` may return the
# same value if called in quick succession.
df.drop_duplicates(inplace=True)
debug_print(f"df no duplicates:
{df}")
print_bar()
if len(df) < 2:
print("Error: not enough data to calculate time precision. Try
"
"increasing `SAMPLE_SIZE` by a factor of 10, and try again.")
exit(1)
# Now calculate the time differences between the timestamps.
df["previous_timestamp_ns"] = df["timestamp_ns"].shift(1)
df = df.dropna() # remove NaN row
df["previous_timestamp_ns"] = df["previous_timestamp_ns"].astype('int64')
df["delta_time_us"] = (
df["timestamp_ns"] - df["previous_timestamp_ns"]) / 1e3
debug_print(f"df:
{df}")
print_bar()
# Output statistics
mean = df["delta_time_us"].mean()
median = df["delta_time_us"].median()
mode = df["delta_time_us"].mode()[0]
stdev = df["delta_time_us"].std()
print(f">>>>>>>>>> {output_stats_header_str} <<<<<<<<<<")
print(f"Mean: {mean:.3f} us")
print(f"Median: {median:.3f} us")
print(f"Mode: {mode:.3f} us")
print(f"Stdev: {stdev:.3f} us")
print(f"FINAL ANSWER: time precision on this system: "
+ f"{median:.3f} +/- {stdev:.3f} us
")
# =============================================================================
# 1. Test `time.monotonic_ns()`
# =============================================================================
SAMPLE_SIZE = SAMPLE_SIZE_DEFAULT
if os.name == 'nt':
# The OS is Windows
if SAMPLE_SIZE < SAMPLE_SIZE_MIN_FOR_WINDOWS:
SAMPLE_SIZE = SAMPLE_SIZE_MIN_FOR_WINDOWS
print(f"Detected: running on Windows. Using a larger SAMPLE_SIZE of "
f"{SAMPLE_SIZE}.
")
# Gather timestamps with zero delays between them
# - preallocated list, so that no dynamic memory allocation will happen in the
# loop below
timestamps_ns = [None]*SAMPLE_SIZE
for i in range(len(timestamps_ns)):
timestamps_ns[i] = time.monotonic_ns()
process_timestamps(timestamps_ns, "1. time.monotonic_ns()")
# =============================================================================
# 2. Test `time.perf_counter_ns()`
# =============================================================================
SAMPLE_SIZE = SAMPLE_SIZE_DEFAULT
timestamps_ns = [None]*SAMPLE_SIZE
for i in range(len(timestamps_ns)):
timestamps_ns[i] = time.perf_counter_ns()
process_timestamps(timestamps_ns, "2. time.perf_counter_ns()")
# =============================================================================
# 3. Test `time.time_ns()`
# =============================================================================
SAMPLE_SIZE = SAMPLE_SIZE_DEFAULT
if os.name == 'nt':
# The OS is Windows
if SAMPLE_SIZE < SAMPLE_SIZE_MIN_FOR_WINDOWS:
SAMPLE_SIZE = SAMPLE_SIZE_MIN_FOR_WINDOWS
print(f"Detected: running on Windows. Using a larger SAMPLE_SIZE of "
f"{SAMPLE_SIZE}.
")
timestamps_ns = [None]*SAMPLE_SIZE
for i in range(len(timestamps_ns)):
timestamps_ns[i] = time.time_ns()
process_timestamps(timestamps_ns, "3. time.time_ns()")
这是我在几台高端 Dell Precision 5570 Pentium i9(Linux)和 i7(Windows 11)20 线程笔记本电脑上运行它时的运行和输出。
在Linux Ubuntu 22.04上(python3 --version
显示Python 3.10.12
):
eRCaGuy_hello_world$ time python/time_monotonic_ns__get_precision.py
>>>>>>>>>> 1. time.monotonic_ns() <<<<<<<<<<
Mean: 0.081 us
Median: 0.070 us
Mode: 0.070 us
Stdev: 0.118 us
FINAL ANSWER: time precision on this system: 0.070 +/- 0.118 us
>>>>>>>>>> 2. time.perf_counter_ns() <<<<<<<<<<
Mean: 0.076 us
Median: 0.069 us
Mode: 0.068 us
Stdev: 0.070 us
FINAL ANSWER: time precision on this system: 0.069 +/- 0.070 us
>>>>>>>>>> 3. time.time_ns() <<<<<<<<<<
Mean: 0.080 us
Median: 0.074 us
Mode: -0.030 us
Stdev: 0.226 us
FINAL ANSWER: time precision on this system: 0.074 +/- 0.226 us
real 0m0.264s
user 0m0.802s
sys 0m1.124s
在Windows 11上(python --version
显示Python 3.12.1
):
eRCaGuy_hello_world$ time python/time_monotonic_ns__get_precision.py
Detected: running on Windows. Using a larger SAMPLE_SIZE of 20000000.
>>>>>>>>>> 1. time.monotonic_ns() <<<<<<<<<<
Mean: 15625.000 us
Median: 16000.000 us
Mode: 16000.000 us
Stdev: 486.897 us
FINAL ANSWER: time precision on this system: 16000.000 +/- 486.897 us
>>>>>>>>>> 2. time.perf_counter_ns() <<<<<<<<<<
Mean: 0.101 us
Median: 0.100 us
Mode: 0.100 us
Stdev: 0.021 us
FINAL ANSWER: time precision on this system: 0.100 +/- 0.021 us
Detected: running on Windows. Using a larger SAMPLE_SIZE of 20000000.
>>>>>>>>>> 3. time.time_ns() <<<<<<<<<<
Mean: 9639.436 us
Median: 10134.354 us
Mode: 610.144 us
Stdev: 5201.053 us
FINAL ANSWER: time precision on this system: 10134.354 +/- 5201.053 us
real 0m8.301s
user 0m0.000s
sys 0m0.000s
每种情况下的中值最能代表您系统所期望的典型分辨率,因为使用中值可以同时消除时间抖动和异常值(与平均值不同,平均值可以消除时间抖动但不消除异常值)。
这充分证明只有该time.perf_counter_ns()
函数在 Windows 和 Linux 上都具有亚微秒的分辨率和精度,这正是我最需要知道的。
未指定时代:
请注意,使用time.monotonic()
或时time.monotonic_ns()
,官方文档说:
返回值的参考点未定义,因此只有两次调用结果之间的差异才有效。
因此,如果您需要绝对日期时间类型的时间戳而不是精度相对时间戳(绝对日期时间包含年、月、日等信息),那么您应该考虑使用datetime
。请参阅此处的答案、下面的评论以及此处的官方文档,特别是此处的官方datetime
文档。以下是如何使用该模块获取时间戳:datetime.now()
from datetime import datetime
now_datetime_object = datetime.now()
但是,不要期望它具有 的分辨率、精度和单调性time.clock_gettime_ns()
。因此,对于计时小差异或进行精确计时工作,time.clock_gettime_ns()
最好选择 。
另一个选项是time.time()
-- 也不能保证“精度优于 1 秒”。您可以使用time.localtime()
或将其转换回日期时间time.gmtime()
。请参阅此处。以下是使用方法:
>>> import time
>>> time.time()
1691442858.8543699
>>> time.localtime(time.time())
time.struct_time(tm_year=2023, tm_mon=8, tm_mday=7, tm_hour=14, tm_min=14, tm_sec=36, tm_wday=0, tm_yday=219, tm_isdst=0)
或者,甚至更好time.time_ns()
::
>>> import time
>>> time.time_ns()
1691443244384978570
>>> time.localtime(time.time_ns()/1e9)
time.struct_time(tm_year=2023, tm_mon=8, tm_mday=7, tm_hour=14, tm_min=20, tm_sec=57, tm_wday=0, tm_yday=219, tm_isdst=0)
>>> time.time_ns()/1e9
1691443263.0889063
Python 3.3 或更高版本
在Windows 上,在 Python 3.3 或更高版本中,您可以使用time.perf_counter()
,如 @ereOn 在这里所示。请参阅:https ://docs.python.org/3/library/time.html#time.perf_counter 。这提供了大约0.5us分辨率的时间戳,以浮点秒为单位。例如:
import time
# For Python 3.3 or later
time_sec = time.perf_counter() # Windows only, I think
# or on Unix or Linux (I think only those)
time_sec = time.monotonic()
Python 3.3 之前的版本(例如:Python 3.0、3.1、3.2)或更高版本
概括:
请参阅我 2016 年在此处的其他答案,了解 Windows 和 Linux 中 0.5 us 分辨率时间戳或更佳时间戳,以及 Python 3.0、3.2 或 3.2 甚至更早的版本!我们通过使用 Python 中的模块调用 C 或 C++共享对象库(Windows 上的 .dll 或 Unix 或 Linux 上的 .so)来实现此目的ctypes
。
我提供以下功能:
millis()
micros()
delay()
delayMicroseconds()
GS_timing.py
从我的eRCaGuy_PyTime repo下载,然后执行以下操作:
import GS_timing
time_ms = GS_timing.millis()
time_us = GS_timing.micros()
GS_timing.delay(10) # delay 10 ms
GS_timing.delayMicroseconds(10000) # delay 10000 us
细节:
2016 年,我使用 Python 3.0 或 3.1 在 Raspberry Pi 上开发一个嵌入式项目,我也经常在 Windows 上测试和运行该项目。我需要纳秒级的分辨率来对超声波传感器进行精确计时。当时的 Python 语言没有提供这种分辨率,也没有对这个问题的答案,所以我在这里提出了一个单独的问答:如何在 Python 中获取毫秒和微秒级分辨率的时间戳?我在当时的问题中说道:
在提出这个问题之前,我读过其他答案,但它们依赖于
time
模块,在 Python 3.3 之前,该模块根本没有任何类型的保证分辨率。它的分辨率到处都是。这里得票最多的答案引用了 Windows 分辨率(使用他们的答案)16 毫秒,这比我在这里提供的答案(0.5 微秒分辨率)差32000 倍。同样,我需要1 毫秒和1 微秒(或类似)的分辨率,而不是 16000 微秒的分辨率。
零,我再说一遍:2016 年 7 月 12 日这里没有一个答案在Python 3.1中对Windows的分辨率优于16 毫秒。因此,我想出了这个答案,它在 Windows 和 Linux 的 Python 3.3之前的版本中具有 0.5us 或更好的分辨率。如果您需要类似的东西用于旧版本的 Python,或者如果您只是想学习如何使用该库在 Python 中调用 C 或 C++ 动态库(Windows 中的 .dll“动态链接库”文件,或 Unix 或 Linux 中的 .so“共享对象”库文件),请参阅我的其他答案。ctypes
参考
我的问答:如何在 Python 中获取毫秒和微秒分辨率的时间戳?
我的回答:如何
DataFrame
在不迭代的情况下迭代 Pandas
解决方案 10:
tiho 在 2014 年 3 月 27 日 17:21 留下的评论值得作为自己的答案:
为了避免特定于平台的代码,请使用 timeit.default_timer()
解决方案 11:
我观察到 Windows 10 专业版和教育版之间 time.time() 的分辨率不同。
在 Windows 10 专业版计算机上,分辨率为 1 毫秒。在 Windows 10 教育版计算机上,分辨率为 16 毫秒。
幸运的是,有一个工具可以提高 Windows 中 Python 的时间分辨率:
https://vvvv.org/contribution/windows-system-timer-tool
使用此工具,无论 Windows 版本如何,我都能实现 1 毫秒的分辨率。您需要在执行 Python 代码时保持它运行。
解决方案 12:
对于那些停留在 Windows(版本 >= Server 2012 或 Win8)和 Python 2.7 上的人来说,
import ctypes
class FILETIME(ctypes.Structure):
_fields_ = [("dwLowDateTime", ctypes.c_uint),
("dwHighDateTime", ctypes.c_uint)]
def time():
"""Accurate version of time.time() for windows, return UTC time in term of seconds since 01/01/1601
"""
file_time = FILETIME()
ctypes.windll.kernel32.GetSystemTimePreciseAsFileTime(ctypes.byref(file_time))
return (file_time.dwLowDateTime + (file_time.dwHighDateTime << 32)) / 1.0e7
GetSystemTimePreciseAsFileTime 函数
解决方案 13:
在同一个 win10 操作系统上使用“两种不同的方法”似乎存在大约“500 纳秒”的时间差。如果您关心纳秒精度,请查看下面的代码。
代码的修改基于用户cod3monk3y
和的代码Kevin S
。
操作系统:python 3.7.3 (default, date, time) [MSC v.1915 64 bit (AMD64)]
def measure1(mean):
for i in range(1, my_range+1):
x = time.time()
td = x- samples1[i-1][2]
if i-1 == 0:
td = 0
td = f'{td:.6f}'
samples1.append((i, td, x))
mean += float(td)
print (mean)
sys.stdout.flush()
time.sleep(0.001)
mean = mean/my_range
return mean
def measure2(nr):
t0 = time.time()
t1 = t0
while t1 == t0:
t1 = time.time()
td = t1-t0
td = f'{td:.6f}'
return (nr, td, t1, t0)
samples1 = [(0, 0, 0)]
my_range = 10
mean1 = 0.0
mean2 = 0.0
mean1 = measure1(mean1)
for i in samples1: print (i)
print ('...
')
samples2 = [measure2(i) for i in range(11)]
for s in samples2:
#print(f'time delta: {s:.4f} seconds')
mean2 += float(s[1])
print (s)
mean2 = mean2/my_range
print ('
Mean1 : ' f'{mean1:.6f}')
print ('Mean2 : ' f'{mean2:.6f}')
测量1的结果:
nr, td, t0
(0, 0, 0)
(1, '0.000000', 1562929696.617988)
(2, '0.002000', 1562929696.6199884)
(3, '0.001001', 1562929696.620989)
(4, '0.001001', 1562929696.62199)
(5, '0.001001', 1562929696.6229906)
(6, '0.001001', 1562929696.6239917)
(7, '0.001001', 1562929696.6249924)
(8, '0.001000', 1562929696.6259928)
(9, '0.001001', 1562929696.6269937)
(10, '0.001001', 1562929696.6279945)
...
测量2的结果:
nr, td , t1, t0
(0, '0.000500', 1562929696.6294951, 1562929696.6289947)
(1, '0.000501', 1562929696.6299958, 1562929696.6294951)
(2, '0.000500', 1562929696.6304958, 1562929696.6299958)
(3, '0.000500', 1562929696.6309962, 1562929696.6304958)
(4, '0.000500', 1562929696.6314962, 1562929696.6309962)
(5, '0.000500', 1562929696.6319966, 1562929696.6314962)
(6, '0.000500', 1562929696.632497, 1562929696.6319966)
(7, '0.000500', 1562929696.6329975, 1562929696.632497)
(8, '0.000500', 1562929696.633498, 1562929696.6329975)
(9, '0.000500', 1562929696.6339984, 1562929696.633498)
(10, '0.000500', 1562929696.6344984, 1562929696.6339984)
最终结果:
平均值1:0.001001#(测量1函数)
平均值2:0.000550#(measure2函数)
解决方案 14:
这是适用于 Windows 的 Python 3 解决方案,基于CyberSnoopy上面发布的答案(使用GetSystemTimePreciseAsFileTime)。我们从jfs借用了一些代码
Python datetime.utcnow() 返回错误的日期时间
并获取以微秒为单位的精确时间戳(Unix 时间)
#! python3
import ctypes.wintypes
def utcnow_microseconds():
system_time = ctypes.wintypes.FILETIME()
#system call used by time.time()
#ctypes.windll.kernel32.GetSystemTimeAsFileTime(ctypes.byref(system_time))
#getting high precision:
ctypes.windll.kernel32.GetSystemTimePreciseAsFileTime(ctypes.byref(system_time))
large = (system_time.dwHighDateTime << 32) + system_time.dwLowDateTime
return large // 10 - 11644473600000000
for ii in range(5):
print(utcnow_microseconds()*1e-6)
参考
https://learn.microsoft.com/en-us/windows/win32/sysinfo/time-functions
解决方案 15:
def start(self):
sec_arg = 10.0
cptr = 0
time_start = time.time()
time_init = time.time()
while True:
cptr += 1
time_start = time.time()
time.sleep(((time_init + (sec_arg * cptr)) - time_start ))
# AND YOUR CODE .......
t00 = threading.Thread(name='thread_request', target=self.send_request, args=([]))
t00.start()
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)