Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pytime.c loses precision under Windows #63937

Closed
pitrou opened this issue Nov 23, 2013 · 10 comments
Closed

pytime.c loses precision under Windows #63937

pitrou opened this issue Nov 23, 2013 · 10 comments
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-feature A feature request or enhancement

Comments

@pitrou
Copy link
Member

pitrou commented Nov 23, 2013

BPO 19738
Nosy @tim-one, @loewis, @pitrou, @vstinner, @larryhastings, @bitdancer

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = <Date 2015-04-09.22:02:58.642>
created_at = <Date 2013-11-23.17:27:12.145>
labels = ['interpreter-core', 'type-feature']
title = 'pytime.c loses precision under Windows'
updated_at = <Date 2015-04-09.22:10:51.830>
user = 'https://github.com/pitrou'

bugs.python.org fields:

activity = <Date 2015-04-09.22:10:51.830>
actor = 'vstinner'
assignee = 'none'
closed = True
closed_date = <Date 2015-04-09.22:02:58.642>
closer = 'vstinner'
components = ['Interpreter Core']
creation = <Date 2013-11-23.17:27:12.145>
creator = 'pitrou'
dependencies = []
files = []
hgrepos = []
issue_num = 19738
keywords = []
message_count = 10.0
messages = ['204063', '204112', '204114', '204117', '204118', '204121', '204132', '240392', '240397', '240399']
nosy_count = 6.0
nosy_names = ['tim.peters', 'loewis', 'pitrou', 'vstinner', 'larry', 'r.david.murray']
pr_nums = []
priority = 'normal'
resolution = 'fixed'
stage = None
status = 'closed'
superseder = None
type = 'enhancement'
url = 'https://bugs.python.org/issue19738'
versions = ['Python 3.5']

@pitrou
Copy link
Member Author

pitrou commented Nov 23, 2013

Under Windows, GetSystemTimeAsFileTime has a 100 ns resolution, but pygettimeofday stores it in a timeval which only has microsecond resolution. As a consequence, some precision is lost under Windows (which shows e.g. in time.time() results).

@pitrou pitrou added interpreter-core (Objects, Python, Grammar, and Parser dirs) type-feature A feature request or enhancement labels Nov 23, 2013
@tim-one
Copy link
Member

tim-one commented Nov 23, 2013

Just noting for the record that a C double (time.time() result) isn't quite enough to hold a full-precision Windows time regardless:

>>> from datetime import date
>>> d = date.today() - date(1970, 1, 1)
>>> s = int(d.total_seconds())  # seconds into "the epoch"
>>> s *= 10**7  # number of 100ns into the epoch
>>> s.bit_length()
54
>>> 54 > 53  # QED ;-)
True

@pitrou
Copy link
Member Author

pitrou commented Nov 23, 2013

Perhaps we need a time_ns() method? (returning an integer timestamp in nanoseconds)

@loewis
Copy link
Mannequin

loewis mannequin commented Nov 23, 2013

I think this issue can be resolved by reducing the loss to the maximum available precision; it's about time.time(), after all.

I don't think pygettimeofday can change; gettimeofday traditionally has only µs. So the issue really is that it is used in implementing time.time().

As for whether an integer-returning current-time function in Python is needed: -1 (but then, I voiced the same concern when the ns-filestamp APIs where added). Adding an API will "force" people to rewrite their code, with no real improvement for practical improvement. The "force" comes from the mere availability of the API, and any emerging claims that using the time_ns() function is "more correct".

I really wish Python would have a 128-bit floating point type that could be used to represent a time stamp. Until such a type is available (perhaps in 2025), I propose that we live with limitations of 64-bit floating point. Anybody *really* needing the Windows system time can use ctypes (or pywin32) already.

@tim-one
Copy link
Member

tim-one commented Nov 23, 2013

I agree overall with Martin, although time.time() could be made a little better on Windows by getting the Windows time directly (instead of "needlessly" losing info by going thru pygettimeofday).

@larryhastings
Copy link
Contributor

Martin: I think the best choice would be a decimal object--which, now that we have decimal in C, is probably sufficiently performant for serious consideration.

@vstinner
Copy link
Member

I think the best choice would be a decimal object--which, now that we have decimal in C, is probably sufficiently performant for serious consideration.

This idea was rejected: see the PEP-410 :-)

@bitdancer
Copy link
Member

Victor, is this issue still relevant given your recent work on time?

@vstinner
Copy link
Member

vstinner commented Apr 9, 2015

Victor, is this issue still relevant given your recent work on time?

In Python 3.3, I modified time.time() to use GetSystemTimeAsFileTime() instead of gettimeofday().

In Python 3.5, I replaced _PyTime_gettimeofday(_PyTime_timeval *tp) (resolution of 1 us) with _PyTime_t _PyTime_GetSystemClock(void) (resolution of 1 ns).

Moreover, most Python functions now use internally a monotonic clock (_PyTime_GetMonotonicClock) instead of the system clock (_PyTime_GetSystemClock), especially to compute timeout. Python 3.5 now ensures that a monotonic clock is available, it checks once at runtime (during Python startup).

The initial issue "pytime.c loses precision under Windows" has been fixed in the issue bpo-22117 which introduced the _PyTime_t type. The resolution of _PyTime_t is no more hardcoded in the API. Currently, it uses a resolution of 1 nanosecond, but it may be worse if we get compilation issues (no 64 bits signed integer type, too bad) or better (ex: if a compiler supports 128 bits signed integer type, I didn't try __int128 of GCC). The resolution is only handled in pytime.c, not in the users of the API.

Martin: I think the best choice would be a decimal object--which, now that we have decimal in C, is probably sufficiently performant for serious consideration.

This change has been discussed in the PEP-410 which has been rejected.

datetime.datetime.now() now uses _PyTime_GetSystemClock() and so indirectly GetSystemTimeAsFileTime() on Windows. Since the datetime type may get nanosecond resolution (issue bpo-15443), it will be possible to get the current time with nanosecond resolution ;-)

I now close the issue.

@vstinner vstinner closed this as completed Apr 9, 2015
@vstinner
Copy link
Member

vstinner commented Apr 9, 2015

Perhaps we need a time_ns() method? (returning an integer timestamp in nanoseconds)

Oh, I missed this message. The current trend in Python (os.stat) is to use a number of nanoseconds to store a timestamp. If we continue this trend in the datetime module, maybe with a new total_nanoseconds() method for example, it may make sense to add a new time.time_ns() function.

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

5 participants