Complete PEP 564 · python/peps@a4828de (original) (raw)

`@@ -80,6 +80,43 @@ The PEP was rejected for different reasons:

`

80

80

` to adapt code to handle it.

`

81

81

``

82

82

``

``

83

`+

Issues caused by precision loss

`

``

84

`+


`

``

85

+

``

86

`+

Example 1: measure time delta

`

``

87

`+

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

`

``

88

+

``

89

`+

A server is running for longer than 104 days. A clock is read before

`

``

90

`+

and after running a function to measure its performance. This benchmark

`

``

91

`+

lose precision only because the float type used by clocks, not because

`

``

92

`+

of the clock resolution.

`

``

93

+

``

94

`+

On Python microbenchmarks, it is common to see function calls taking

`

``

95

`+

less than 100 ns. A difference of a single nanosecond becomes

`

``

96

`+

significant.

`

``

97

+

``

98

`+

Example 2: compare time with different resolution

`

``

99

`+

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

`

``

100

+

``

101

`+

Two programs "A" and "B" are runing on the same system, so use the system

`

``

102

`+

block. The program A reads the system clock with nanosecond resolution

`

``

103

`+

and writes the timestamp with nanosecond resolution. The program B reads

`

``

104

`+

the timestamp with nanosecond resolution, but compares it to the system

`

``

105

`+

clock read with a worse resolution. To simplify the example, let's say

`

``

106

`+

that it reads the clock with second resolution. If that case, there is a

`

``

107

`+

window of 1 second while the program B can see the timestamp written by A

`

``

108

`+

as "in the future".

`

``

109

+

``

110

`+

Nowadays, more and more databases and filesystems support storing time

`

``

111

`+

with nanosecond resolution.

`

``

112

+

``

113

`+

.. note::

`

``

114

`+

This issue was already fixed for file modification time by adding the

`

``

115


 ``st_mtime_ns`` field to the ``os.stat()`` result, and by accepting

``

116


 nanoseconds in ``os.utime()``. This PEP proposes to generalize the

``

117

`+

fix.

`

``

118

+

``

119

+

83

120

`CPython enhancements of the last 5 years

`

84

121

`----------------------------------------

`

85

122

``

`@@ -187,24 +224,37 @@ UNIX epoch as reference, this type supports time since year 1677 to year

`

187

224

` >>> 1970 + 2 ** 63 / (10 ** 9 * 3600 * 24 * 365.25)

`

188

225

` 2262.271023045313

`

189

226

``

``

227

`+

Modify time.time() result type

`

``

228

`+


`

``

229

+

``

230


It was proposed to modify ``time.time()`` to return a different float

``

231

`+

type with better precision.

`

``

232

+

``

233


The PEP 410 proposed to use ``decimal.Decimal`` which already exists and

``

234

`+

supports arbitray precision, but it was rejected. Apart

`

``

235


``decimal.Decimal``, no portable ``float`` type with better precision is

``

236

`+

currently available in Python.

`

``

237

+

``

238


Changing the builtin Python ``float`` type is out of the scope of this

``

239

`+

PEP.

`

``

240

+

``

241

`+

Moreover, changing existing functions to return a new type introduces a

`

``

242

`+

risk of breaking the backward compatibility even the new type is

`

``

243

`+

designed carefully.

`

``

244

+

``

245

+

190

246

`Different types

`

191

247

`---------------

`

192

248

``

193

``


It was proposed to modify ``time.time()`` to use float type with better

194

``


precision. The PEP 410 proposed to use ``decimal.Decimal``, but it was

195

``


rejected. Apart ``decimal.Decimal``, no portable ``float`` type with

196

``

`-

better precision is currently available in Python. Changing the builtin

`

197

``


Python ``float`` type is out of the scope of this PEP.

198

``

-

199

``

`-

Other ideas of new types were proposed to support larger or arbitrary

`

``

249

`+

Many ideas of new types were proposed to support larger or arbitrary

`

200

250

`precision: fractions, structures or 2-tuple using integers,

`

201

251

`fixed-precision floating point number, etc.

`

202

252

``

203

253

`See also the PEP 410 for a previous long discussion on other types.

`

204

254

``

205

255

`Adding a new type requires more effort to support it, than reusing

`

206

``


``int``. The standard library, third party code and applications would

207

``

`-

have to be modified to support it.

`

``

256


the existing ``int`` type. The standard library, third party code and

``

257

`+

applications would have to be modified to support it.

`

208

258

``

209

259

``` The Python int type is well known, well supported, ease to


`210`

`260`

`manipulate, and supports all arithmetic operations like:

`

``` @@ -233,6 +283,30 @@ seconds (``time.time()`` returning ``float``) and nanoseconds

233

283

`there is no need for resolution better than 1 nanosecond in practive in

`

234

284

`the Python standard library.

`

235

285

``

``

286

`+

New time_ns module

`

``

287

`+


`

``

288

+

``

289


Add a new ``time_ns`` module which contains the five new functions:

``

290

+

``

291


* ``time_ns.clock_gettime(clock_id)``

``

292


* ``time_ns.clock_settime(clock_id, time: int)``

``

293


* ``time_ns.perf_counter()``

``

294


* ``time_ns.monotonic()``

``

295


* ``time_ns.time()``

``

296

+

``

297


The first question is if the ``time_ns`` should expose exactly the same

``

298


API (constants, functions, etc.) than the ``time`` module. It can be

``

299


painful to maintain two flavors of the ``time`` module. How users use

``

300

`+

suppose to make a choice between these two modules?

`

``

301

+

``

302


If tomorrow, other nanosecond variant are needed in the ``os`` module,

``

303


will we have to add a new ``os_ns`` module as well? There are functions

``

304


related to time in many modules: ``time``, ``os``, ``signal``,

``

305


``resource``, ``select``, etc.

``

306

+

``

307


Another idea is to add a ``time.ns`` submodule or a nested-namespace to

``

308


get the ``time.ns.time()`` syntax.

``

309

+

236

310

``

237

311

`Annex: Clocks Resolution in Python

`

238

312

`==================================

`