Re: [Python-Dev] cpython: Issue #10278: Add an optional strict argument to time.steady(), False by default

2012-03-20 Thread Steven D'Aprano
On Mon, Mar 19, 2012 at 01:35:49PM +0100, Victor Stinner wrote:

 Said differently: time.steady(strict=True) is always monotonic (*),
 whereas time.steady() may or may not be monotonic, depending on what
 is avaiable.
 
 time.steady() is a best-effort steady clock.
 
 (*) time.steady(strict=True) relies on the OS monotonic clock. If the
 OS provides a not really monotonic clock, Python cannot do better.

I don't think that is true. Surely Python can guarantee that the clock 
will never go backwards by caching the last value. A sketch of an 
implementation:

def monotonic(_last=[None]):
t = system_clock()  # best effort, but sometimes goes backwards
if _last[0] is not None:
t = max(t, _last[0])
_last[0] = t
return t

Overhead if done in Python may be excessive, in which case do it in C.

Unless I've missed something, that guarantees monotonicity -- it may not 
advance from one call to the next, but it will never go backwards.

There's probably even a cleverer implementation that will not repeat the 
same value more than twice in a row. I leave that as an exercise :)

As far as I can tell, steady is a misnomer. We can't guarantee that 
the timer will tick at a steady rate. That will depend on the quality of 
the hardware clock.


-- 
Steven

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] cpython: Issue #10278: Add an optional strict argument to time.steady(), False by default

2012-03-20 Thread Matt Joiner
I believe we should make a monotonic_time method that assures monotonicity
and be done with it. Forward steadiness can not be guaranteed. No
parameters.
On Mar 20, 2012 2:56 PM, Steven Dapos;Aprano st...@pearwood.info wrote:

 On Mon, Mar 19, 2012 at 01:35:49PM +0100, Victor Stinner wrote:

  Said differently: time.steady(strict=True) is always monotonic (*),
  whereas time.steady() may or may not be monotonic, depending on what
  is avaiable.
 
  time.steady() is a best-effort steady clock.
 
  (*) time.steady(strict=True) relies on the OS monotonic clock. If the
  OS provides a not really monotonic clock, Python cannot do better.

 I don't think that is true. Surely Python can guarantee that the clock
 will never go backwards by caching the last value. A sketch of an
 implementation:

 def monotonic(_last=[None]):
t = system_clock()  # best effort, but sometimes goes backwards
if _last[0] is not None:
t = max(t, _last[0])
_last[0] = t
return t

 Overhead if done in Python may be excessive, in which case do it in C.

 Unless I've missed something, that guarantees monotonicity -- it may not
 advance from one call to the next, but it will never go backwards.

 There's probably even a cleverer implementation that will not repeat the
 same value more than twice in a row. I leave that as an exercise :)

 As far as I can tell, steady is a misnomer. We can't guarantee that
 the timer will tick at a steady rate. That will depend on the quality of
 the hardware clock.


 --
 Steven

 ___
 Python-Dev mailing list
 Python-Dev@python.org
 http://mail.python.org/mailman/listinfo/python-dev
 Unsubscribe:
 http://mail.python.org/mailman/options/python-dev/anacrolix%40gmail.com

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] cpython: Issue #10278: Add an optional strict argument to time.steady(), False by default

2012-03-20 Thread Glyph

On Mar 20, 2012, at 3:33 AM, Matt Joiner wrote:

 I believe we should make a monotonic_time method that assures monotonicity 
 and be done with it. Forward steadiness can not be guaranteed. No parameters.
 

I think this discussion has veered off a bit into the overly-theoretical.  
Python cannot really guarantee anything here; alternately, it guarantees 
everything, since if you don't like what Python gives you you can always get 
your money back :).  It's the OS's job to guarantee things.  We can all agree 
that a monotonic clock of some sort is useful.

However, maybe my application wants CLOCK_MONOTONIC and maybe it wants 
CLOCK_MONOTONIC_RAW.  Sometimes I want GetTickCount64 and sometimes I want 
QueryUnbiasedInterruptTime.  While these distinctions are probably useless to 
most applications, they may be of interest to some, and Python really shouldn't 
make it unduly difficult to get at them.

-glyph___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] cpython: Issue #10278: Add an optional strict argument to time.steady(), False by default

2012-03-20 Thread Victor Stinner
 I think this discussion has veered off a bit into the overly-theoretical.
  Python cannot really guarantee anything here

That's why the function name was changed from time.monotonic() to
time.steady(strict=True). If you want to change something, you should
change the documentation to list OS limitations.

 It's the OS's job to guarantee things

Correct, most Python modules exposing OS functions are thin wrappers
and don't add any magic. When we need a higher level API, we write a
new module: like shutil enhancing the os module.

Victor
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] cpython: Issue #10278: Add an optional strict argument to time.steady(), False by default

2012-03-20 Thread R. David Murray
On Tue, 20 Mar 2012 04:43:44 -0400, Glyph gl...@twistedmatrix.com wrote:
 
 On Mar 20, 2012, at 3:33 AM, Matt Joiner wrote:
 
  I believe we should make a monotonic_time method that assures monotonicity 
  and be done with it. Forward steadiness can not be guaranteed. No 
  parameters.
  
 
 I think this discussion has veered off a bit into the overly-theoretical.  
 Python cannot really guarantee anything here; alternately, it guarantees 
 everything, since if you don't like what Python gives you you can always get 
 your money back :).  It's the OS's job to guarantee things.  We can all agree 
 that a monotonic clock of some sort is useful.
 
 However, maybe my application wants CLOCK_MONOTONIC and maybe it wants 
 CLOCK_MONOTONIC_RAW.  Sometimes I want GetTickCount64 and sometimes I want 
 QueryUnbiasedInterruptTime.  While these distinctions are probably useless to 
 most applications, they may be of interest to some, and Python really 
 shouldn't make it unduly difficult to get at them.

Something like:

time.steady(require_clock=None)

where require_clock can be any of BEST, CLOCK_MONOTONIC, CLOCK_MONOTONIC_RAW,
GetTickCount64, QueryUnbiastedInterruptTime, etc?  Then None would mean
it is allowable to use time.time and the cache-the-last-time-returned
algorithm, and BEST would be Victor's current 'strict=True'.  And if you
require a Linux clock on Windows or vice-versa, on your own head be it :)

--David
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] cpython: Issue #10278: Add an optional strict argument to time.steady(), False by default

2012-03-19 Thread Victor Stinner
 I have to agree with Georg. Looking at the code, it appears OSError can
 be raised with both strict=True and strict=False (since floattime() can
 raise OSError).

This is an old bug in floattime(): I opened the issue #14368 to remove
the unused exception. In practice, it never happens (or it is *very*
unlikely today). IMO it's a bug in floattime().

 I also think By default, if strict is False confuses things.

I agree, I replaced it by By default,.

Victor
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] cpython: Issue #10278: Add an optional strict argument to time.steady(), False by default

2012-03-19 Thread Victor Stinner
 This is not clear to me.  Why wouldn't it raise OSError on error even with
 strict=False?  Please clarify which exception is raised in which case.

 It seems clear to me. It doesn't raise exceptions when strict=False because
 it falls back to a non-monotonic clock. If strict is True and a non-monotonic
 clock is not available it raises OSError or NotImplementedError.

 So errors are ignored when strict is false?

Said differently: time.steady(strict=True) is always monotonic (*),
whereas time.steady() may or may not be monotonic, depending on what
is avaiable.

time.steady() is a best-effort steady clock.

(*) time.steady(strict=True) relies on the OS monotonic clock. If the
OS provides a not really monotonic clock, Python cannot do better.
For example, clock_gettime(CLOCK_MONOTONIC) speed can be adjusted by
NTP on Linux. Python tries to use clock_gettime(CLOCK_MONOTONIC_RAW)
which doesn't have this issue.

Victor
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] cpython: Issue #10278: Add an optional strict argument to time.steady(), False by default

2012-03-17 Thread Georg Brandl
On 03/15/2012 01:17 AM, victor.stinner wrote:
 http://hg.python.org/cpython/rev/27441e0d6a75
 changeset:   75672:27441e0d6a75
 user:Victor Stinner victor.stin...@gmail.com
 date:Thu Mar 15 01:17:09 2012 +0100
 summary:
   Issue #10278: Add an optional strict argument to time.steady(), False by 
 default
 
 files:
   Doc/library/time.rst  |   7 +++-
   Lib/test/test_time.py |  10 +
   Modules/timemodule.c  |  58 +-
   3 files changed, 57 insertions(+), 18 deletions(-)
 
 
 diff --git a/Doc/library/time.rst b/Doc/library/time.rst
 --- a/Doc/library/time.rst
 +++ b/Doc/library/time.rst
 @@ -226,7 +226,7 @@
 The earliest date for which it can generate a time is platform-dependent.
  
  
 -.. function:: steady()
 +.. function:: steady(strict=False)
  
 .. index::
single: benchmarking
 @@ -236,6 +236,11 @@
 adjusted. The reference point of the returned value is undefined so only 
 the
 difference of consecutive calls is valid.
  
 +   If available, a monotonic clock is used. By default, if *strict* is False,
 +   the function falls back to another clock if the monotonic clock failed or 
 is
 +   not available. If *strict* is True, raise an :exc:`OSError` on error or
 +   :exc:`NotImplementedError` if no monotonic clock is available.

This is not clear to me.  Why wouldn't it raise OSError on error even with
strict=False?  Please clarify which exception is raised in which case.

Georg

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] cpython: Issue #10278: Add an optional strict argument to time.steady(), False by default

2012-03-17 Thread Michael Foord

On 17 Mar 2012, at 08:49, Georg Brandl wrote:

 On 03/15/2012 01:17 AM, victor.stinner wrote:
 http://hg.python.org/cpython/rev/27441e0d6a75
 changeset:   75672:27441e0d6a75
 user:Victor Stinner victor.stin...@gmail.com
 date:Thu Mar 15 01:17:09 2012 +0100
 summary:
  Issue #10278: Add an optional strict argument to time.steady(), False by 
 default
 
 files:
  Doc/library/time.rst  |   7 +++-
  Lib/test/test_time.py |  10 +
  Modules/timemodule.c  |  58 +-
  3 files changed, 57 insertions(+), 18 deletions(-)
 
 
 diff --git a/Doc/library/time.rst b/Doc/library/time.rst
 --- a/Doc/library/time.rst
 +++ b/Doc/library/time.rst
 @@ -226,7 +226,7 @@
The earliest date for which it can generate a time is platform-dependent.
 
 
 -.. function:: steady()
 +.. function:: steady(strict=False)
 
.. index::
   single: benchmarking
 @@ -236,6 +236,11 @@
adjusted. The reference point of the returned value is undefined so only 
 the
difference of consecutive calls is valid.
 
 +   If available, a monotonic clock is used. By default, if *strict* is 
 False,
 +   the function falls back to another clock if the monotonic clock failed 
 or is
 +   not available. If *strict* is True, raise an :exc:`OSError` on error or
 +   :exc:`NotImplementedError` if no monotonic clock is available.
 
 This is not clear to me.  Why wouldn't it raise OSError on error even with
 strict=False?  Please clarify which exception is raised in which case.

It seems clear to me. It doesn't raise exceptions when strict=False because it 
falls back to a non-monotonic clock. If strict is True and a non-monotonic 
clock is not available it raises OSError or NotImplementedError.

Michael

 
 Georg
 
 ___
 Python-Dev mailing list
 Python-Dev@python.org
 http://mail.python.org/mailman/listinfo/python-dev
 Unsubscribe: 
 http://mail.python.org/mailman/options/python-dev/fuzzyman%40voidspace.org.uk
 


--
http://www.voidspace.org.uk/


May you do good and not evil
May you find forgiveness for yourself and forgive others
May you share freely, never taking more than you give.
-- the sqlite blessing 
http://www.sqlite.org/different.html





___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] cpython: Issue #10278: Add an optional strict argument to time.steady(), False by default

2012-03-17 Thread Georg Brandl
On 03/17/2012 09:47 PM, Michael Foord wrote:
 
 On 17 Mar 2012, at 08:49, Georg Brandl wrote:
 
 On 03/15/2012 01:17 AM, victor.stinner wrote:
 http://hg.python.org/cpython/rev/27441e0d6a75 changeset:
 75672:27441e0d6a75 user:Victor Stinner
 victor.stin...@gmail.com date:Thu Mar 15 01:17:09 2012 +0100 
 summary: Issue #10278: Add an optional strict argument to time.steady(),
 False by default
 
 files: Doc/library/time.rst  |   7 +++- Lib/test/test_time.py |  10
 + Modules/timemodule.c  |  58 +- 3 files
 changed, 57 insertions(+), 18 deletions(-)
 
 
 diff --git a/Doc/library/time.rst b/Doc/library/time.rst ---
 a/Doc/library/time.rst +++ b/Doc/library/time.rst @@ -226,7 +226,7 @@ The
 earliest date for which it can generate a time is platform-dependent.
 
 
 -.. function:: steady() +.. function:: steady(strict=False)
 
 .. index:: single: benchmarking @@ -236,6 +236,11 @@ adjusted. The
 reference point of the returned value is undefined so only the difference
 of consecutive calls is valid.
 
 +   If available, a monotonic clock is used. By default, if *strict* is
 False, +   the function falls back to another clock if the monotonic
 clock failed or is +   not available. If *strict* is True, raise an
 :exc:`OSError` on error or +   :exc:`NotImplementedError` if no monotonic
 clock is available.
 
 This is not clear to me.  Why wouldn't it raise OSError on error even with 
 strict=False?  Please clarify which exception is raised in which case.
 
 It seems clear to me. It doesn't raise exceptions when strict=False because
 it falls back to a non-monotonic clock. If strict is True and a non-monotonic
 clock is not available it raises OSError or NotImplementedError.

So errors are ignored when strict is false?

Georg

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] cpython: Issue #10278: Add an optional strict argument to time.steady(), False by default

2012-03-17 Thread Eric V. Smith
On 3/17/2012 4:47 PM, Michael Foord wrote:
 
 On 17 Mar 2012, at 08:49, Georg Brandl wrote:
 
 On 03/15/2012 01:17 AM, victor.stinner wrote:

 +   If available, a monotonic clock is used. By default, if *strict* is 
 False,
 +   the function falls back to another clock if the monotonic clock failed 
 or is
 +   not available. If *strict* is True, raise an :exc:`OSError` on error or
 +   :exc:`NotImplementedError` if no monotonic clock is available.

 This is not clear to me.  Why wouldn't it raise OSError on error even with
 strict=False?  Please clarify which exception is raised in which case.
 
 It seems clear to me. It doesn't raise exceptions when strict=False because 
 it falls back to a non-monotonic clock. If strict is True and a non-
 monotonic clock is not available it raises OSError or NotImplementedError.

I have to agree with Georg. Looking at the code, it appears OSError can
be raised with both strict=True and strict=False (since floattime() can
raise OSError). The text needs to make it clear OSError can always be
raised.

I also think By default, if strict is False confuses things. If
there's a default behavior with strict=False, what's the non-default
behavior? I suggest dropping By default.

Eric.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] cpython: Issue #10278: Add an optional strict argument to time.steady(), False by default

2012-03-17 Thread Michael Foord

On 17 Mar 2012, at 15:04, Georg Brandl wrote:

 On 03/17/2012 09:47 PM, Michael Foord wrote:
 
 On 17 Mar 2012, at 08:49, Georg Brandl wrote:
 
 On 03/15/2012 01:17 AM, victor.stinner wrote:
 http://hg.python.org/cpython/rev/27441e0d6a75 changeset:
 75672:27441e0d6a75 user:Victor Stinner
 victor.stin...@gmail.com date:Thu Mar 15 01:17:09 2012 +0100 
 summary: Issue #10278: Add an optional strict argument to time.steady(),
 False by default
 
 files: Doc/library/time.rst  |   7 +++- Lib/test/test_time.py |  10
 + Modules/timemodule.c  |  58 +- 3 files
 changed, 57 insertions(+), 18 deletions(-)
 
 
 diff --git a/Doc/library/time.rst b/Doc/library/time.rst ---
 a/Doc/library/time.rst +++ b/Doc/library/time.rst @@ -226,7 +226,7 @@ The
 earliest date for which it can generate a time is platform-dependent.
 
 
 -.. function:: steady() +.. function:: steady(strict=False)
 
 .. index:: single: benchmarking @@ -236,6 +236,11 @@ adjusted. The
 reference point of the returned value is undefined so only the difference
 of consecutive calls is valid.
 
 +   If available, a monotonic clock is used. By default, if *strict* is
 False, +   the function falls back to another clock if the monotonic
 clock failed or is +   not available. If *strict* is True, raise an
 :exc:`OSError` on error or +   :exc:`NotImplementedError` if no monotonic
 clock is available.
 
 This is not clear to me.  Why wouldn't it raise OSError on error even with 
 strict=False?  Please clarify which exception is raised in which case.
 
 It seems clear to me. It doesn't raise exceptions when strict=False because
 it falls back to a non-monotonic clock. If strict is True and a non-monotonic
 clock is not available it raises OSError or NotImplementedError.
 
 So errors are ignored when strict is false?


Well, as described in the documentation an error in finding a monotonic clock 
causes the function to fallback to a different clock. So you could interpret 
that as either errors are ignored, or it isn't an error in the first place. I 
don't see how the following is ambiguous, but you're obviously having 
difficulty with it. Perhaps you can suggest another wording.

if *strict* is False, the function falls back to another clock if the 
monotonic clock failed or is not available. 

The note from Eric notwithstanding though.

Michael

 
 Georg
 
 ___
 Python-Dev mailing list
 Python-Dev@python.org
 http://mail.python.org/mailman/listinfo/python-dev
 Unsubscribe: 
 http://mail.python.org/mailman/options/python-dev/fuzzyman%40voidspace.org.uk
 


--
http://www.voidspace.org.uk/


May you do good and not evil
May you find forgiveness for yourself and forgive others
May you share freely, never taking more than you give.
-- the sqlite blessing 
http://www.sqlite.org/different.html





___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com