GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing peps.python.org — PEP 564 – Add new time functions with nanosecond resolution | peps.python.org
PEP 564 – Add new time functions with nanosecond resolution
PEP 564 – Add new time functions with nanosecond resolution
AbstractAdd six new “nanosecond” variants of existing functions to the The RationaleFloat type limited to 104 daysThe clocks resolution of desktop and laptop computers is getting closer to nanosecond resolution. More and more clocks have a frequency in MHz, up to GHz for the CPU TSC clock. The Python The problem is that the # no precision loss >>> x = 2 ** 52 + 1; int(float(x * 1e-9) * 1e9) - x 0 # precision loss! (1 nanosecond) >>> x = 2 ** 53 + 1; int(float(x * 1e-9) * 1e9) - x -1 >>> print(datetime.timedelta(seconds=2 ** 53 / 1e9)) 104 days, 5:59:59.254741
>>> import datetime >>> unix_epoch = datetime.datetime(1970, 1, 1) >>> print(unix_epoch + datetime.timedelta(seconds=2**53 / 1e9)) 1970-04-15 05:59:59.254741 Previous rejected PEPFive years ago, the PEP 410 proposed a large and complex change in all
Python functions returning time to support nanosecond resolution using
the The PEP was rejected for different reasons:
Issues caused by precision lossExample 1: measure time delta in long-running processA server is running for longer than 104 days. A clock is read before and after running a function to measure its performance to detect performance issues at runtime. Such benchmark only loses precision because of the float type used by clocks, not because of the clock resolution. On Python microbenchmarks, it is common to see function calls taking less than 100 ns. A difference of a few nanoseconds might become significant. Example 2: compare times with different resolutionTwo programs “A” and “B” are running on the same system and use the system clock. The program A reads the system clock with nanosecond resolution and writes a timestamp with nanosecond resolution. The program B reads the timestamp with nanosecond resolution, but compares it to the system clock read with a worse resolution. To simplify the example, let’s say that B reads the clock with second resolution. If that case, there is a window of 1 second while the program B can see the timestamp written by A as “in the future”. Nowadays, more and more databases and filesystems support storing times with nanosecond resolution. Note This issue was already fixed for file modification time by adding the
CPython enhancements of the last 5 yearsSince the PEP 410 was rejected:
Existing Python APIs using nanoseconds as intThe The ChangesNew functionsThis PEP adds six new functions to the
These functions are similar to the version without the For example, These functions are needed because they may return “large” timestamps,
like Unchanged functionsSince the Python has other time-returning functions. No nanosecond variant is
proposed for these other functions, either because their internal
resolution is greater or equal to 1 us, or because their maximum value
is small enough to not lose precision. For example, the maximum value of
Examples of unchanged functions:
See also the Annex: Clocks Resolution in Python. A new nanosecond-returning flavor of these functions may be added later if an operating system exposes new functions providing better resolution. Alternatives and discussionSub-nanosecond resolution
In practice, the 1 nanosecond resolution is currently enough for all structures returned by all common operating systems functions. Hardware clocks with a resolution better than 1 nanosecond already exist. For example, the frequency of a CPU TSC clock is the CPU base frequency: the resolution is around 0.3 ns for a CPU running at 3 GHz. Users who have access to such hardware and really need sub-nanosecond resolution can however extend Python for their needs. Such a rare use case doesn’t justify to design the Python standard library to support sub-nanosecond resolution. For the CPython implementation, nanosecond resolution is convenient: the
standard and well supported >>> 1970 - 2 ** 63 / (10 ** 9 * 3600 * 24 * 365.25) 1677.728976954687 >>> 1970 + 2 ** 63 / (10 ** 9 * 3600 * 24 * 365.25) 2262.271023045313 Modifying time.time() result typeIt was proposed to modify The PEP 410 proposed to return Changing the built-in Python Moreover, changing existing functions to return a new type introduces a risk of breaking the backward compatibility even if the new type is designed carefully. Different typesMany ideas of new types were proposed to support larger or arbitrary precision: fractions, structures or 2-tuple using integers, fixed-point number, etc. See also the PEP 410 for a previous long discussion on other types. Adding a new type requires more effort to support it, than reusing
the existing The Python Moreover, taking/returning an integer number of nanoseconds is not a
new concept in Python, as witnessed by Note If the Python Different APIThe Different options were proposed to allow the user to choose the time
resolution. If each Python module uses a different resolution, it can
become difficult to handle different resolutions, instead of just
seconds ( A new moduleIt was proposed to add a new
The first question is whether the If tomorrow, other nanosecond variants are needed in the Another idea is to add a Annex: Clocks Resolution in PythonThis annex contains the resolution of clocks as measured in Python, and not the resolution announced by the operating system or the resolution of the internal structure used by the operating system. ScriptExample of script to measure the smallest difference between two
import math import time LOOPS = 10 ** 6 print("time.time_ns(): %s" % time.time_ns()) print("time.time(): %s" % time.time()) min_dt = [abs(time.time_ns() - time.time_ns()) for _ in range(LOOPS)] min_dt = min(filter(bool, min_dt)) print("min time_ns() delta: %s ns" % min_dt) min_dt = [abs(time.time() - time.time()) for _ in range(LOOPS)] min_dt = min(filter(bool, min_dt)) print("min time() delta: %s ns" % math.ceil(min_dt * 1e9)) LinuxClocks resolution measured in Python on Fedora 26 (kernel 4.12):
Notes on resolutions:
WindowsClocks resolution measured in Python on Windows 8.1:
The frequency of AnalysisThe resolution of The difference between
Note Internally, Python starts LinksCopyrightThis document has been placed in the public domain. | ||||||||||||||||||||||||||||||||||||||||||||
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |