Re: [webkit-dev] RFC: stop using std::chrono, go back to using doubles for time

2016-11-04 Thread Filip Pizlo
EWS doesn't hate it anymore!

Reviews welcome.  I've been slowly integrating feedback as I've received it.

-Filip



> On Nov 4, 2016, at 11:52 AM, Filip Pizlo  wrote:
> 
> Haha, I'm fixing it!
> 
> I could use a review of the time API even while I fix some broken corners in 
> WebCore and WK2.
> 
> -Filip
> 
> 
>> On Nov 4, 2016, at 11:31 AM, Brent Fulgham > > wrote:
>> 
>> EWS Hates your patch! :-)
>> 
>>> On Nov 4, 2016, at 10:01 AM, Filip Pizlo >> > wrote:
>>> 
>>> Hi everyone!
>>> 
>>> That last time we talked about this, there seemed to be a lot of agreement 
>>> that we should go with the Seconds/MonotonicTime/WallTime approach.
>>> 
>>> I have implemented it: https://bugs.webkit.org/show_bug.cgi?id=152045 
>>> 
>>> 
>>> That patch just takes a subset of our time code - all of the stuff that 
>>> transitively touches ParkingLot - and converts it to use the new time 
>>> classes.  Reviews welcome!
>>> 
>>> -Filip
>>> 
>>> 
>>> 
 On May 22, 2016, at 6:41 PM, Filip Pizlo > wrote:
 
 Hi everyone!
 
 I’d like us to stop using std::chrono and go back to using doubles for 
 time.  First I list the things that I think we wanted to get from 
 std::chrono - the reasons why we started switching to it in the first 
 place.  Then I list some disadvantages of std::chrono that we've seen from 
 fixing std::chrono-based code.  Finally I propose some options for how to 
 use doubles for time.
 
 Why we switched to std::chrono
 
 A year ago we started using std::chrono for measuring time.  std::chrono 
 has a rich typesystem for expressing many different kinds of time.  For 
 example, you can distinguish between an absolute point in time and a 
 relative time.  And you can distinguish between different units, like 
 nanoseconds, milliseconds, etc.
 
 Before this, we used doubles for time.  std::chrono’s advantages over 
 doubles are:
 
 Easy to remember what unit is used: We sometimes used doubles for 
 milliseconds and sometimes for seconds.  std::chrono prevents you from 
 getting the two confused.
 
 Easy to remember what kind of clock is used: We sometimes use the 
 monotonic clock and sometimes the wall clock (aka the real time clock).  
 Bad things would happen if we passed a time measured using the monotonic 
 clock to functions that expected time measured using the wall clock, and 
 vice-versa.  I know that I’ve made this mistake in the past, and it can be 
 painful to debug.
 
 In short, std::chrono uses compile-time type checking to catch some bugs.
 
 Disadvantages of using std::chrono
 
 We’ve seen some problems with std::chrono, and I think that the problems 
 outweigh the advantages.  std::chrono suffers from a heavily templatized 
 API that results in template creep in our own internal APIs.  
 std::chrono’s default of integers without overflow protection means that 
 math involving std::chrono is inherently more dangerous than math 
 involving double.  This is particularly bad when we use time to speak 
 about timeouts.
 
 Too many templates: std::chrono uses templates heavily.  It’s overkill for 
 measuring time.  This leads to verbosity and template creep throughout 
 common algorithms that take time as an argument.  For example if we use 
 doubles, a method for sleeping for a second might look like 
 sleepForSeconds(double).  This works even if someone wants to sleep for a 
 nanoseconds, since 0.01 is easy to represent using a double.  Also, 
 multiplying or dividing a double by a small constant factor (1,000,000,000 
 is small by double standards) is virtually guaranteed to avoid any loss of 
 precision.  But as soon as such a utility gets std::chronified, it becomes 
 a template.  This is because you cannot have 
 sleepFor(std::chrono::seconds), since that wouldn’t allow you to represent 
 fractions of seconds.  This brings me to my next point.
 
 Overflow danger: std::chrono is based on integers and its math methods do 
 not support overflow protection.  This has led to serious bugs like 
 https://bugs.webkit.org/show_bug.cgi?id=157924 
 .  This cancels out the 
 “remember what unit is used” benefit cited above.  It’s true that I know 
 what type of time I have, but as soon as I duration_cast it to another 
 unit, I may overflow.  The type system does not help!  This is insane: 
 std::chrono requires you to do more work when writing multi-unit code, so 
 that you satisfy the type checker, but you still have to be just as 
 paranoid around multi-unit scenarios.  

Re: [webkit-dev] RFC: stop using std::chrono, go back to using doubles for time

2016-11-04 Thread Filip Pizlo
Haha, I'm fixing it!

I could use a review of the time API even while I fix some broken corners in 
WebCore and WK2.

-Filip


> On Nov 4, 2016, at 11:31 AM, Brent Fulgham  wrote:
> 
> EWS Hates your patch! :-)
> 
>> On Nov 4, 2016, at 10:01 AM, Filip Pizlo > > wrote:
>> 
>> Hi everyone!
>> 
>> That last time we talked about this, there seemed to be a lot of agreement 
>> that we should go with the Seconds/MonotonicTime/WallTime approach.
>> 
>> I have implemented it: https://bugs.webkit.org/show_bug.cgi?id=152045 
>> 
>> 
>> That patch just takes a subset of our time code - all of the stuff that 
>> transitively touches ParkingLot - and converts it to use the new time 
>> classes.  Reviews welcome!
>> 
>> -Filip
>> 
>> 
>> 
>>> On May 22, 2016, at 6:41 PM, Filip Pizlo >> > wrote:
>>> 
>>> Hi everyone!
>>> 
>>> I’d like us to stop using std::chrono and go back to using doubles for 
>>> time.  First I list the things that I think we wanted to get from 
>>> std::chrono - the reasons why we started switching to it in the first 
>>> place.  Then I list some disadvantages of std::chrono that we've seen from 
>>> fixing std::chrono-based code.  Finally I propose some options for how to 
>>> use doubles for time.
>>> 
>>> Why we switched to std::chrono
>>> 
>>> A year ago we started using std::chrono for measuring time.  std::chrono 
>>> has a rich typesystem for expressing many different kinds of time.  For 
>>> example, you can distinguish between an absolute point in time and a 
>>> relative time.  And you can distinguish between different units, like 
>>> nanoseconds, milliseconds, etc.
>>> 
>>> Before this, we used doubles for time.  std::chrono’s advantages over 
>>> doubles are:
>>> 
>>> Easy to remember what unit is used: We sometimes used doubles for 
>>> milliseconds and sometimes for seconds.  std::chrono prevents you from 
>>> getting the two confused.
>>> 
>>> Easy to remember what kind of clock is used: We sometimes use the monotonic 
>>> clock and sometimes the wall clock (aka the real time clock).  Bad things 
>>> would happen if we passed a time measured using the monotonic clock to 
>>> functions that expected time measured using the wall clock, and vice-versa. 
>>>  I know that I’ve made this mistake in the past, and it can be painful to 
>>> debug.
>>> 
>>> In short, std::chrono uses compile-time type checking to catch some bugs.
>>> 
>>> Disadvantages of using std::chrono
>>> 
>>> We’ve seen some problems with std::chrono, and I think that the problems 
>>> outweigh the advantages.  std::chrono suffers from a heavily templatized 
>>> API that results in template creep in our own internal APIs.  std::chrono’s 
>>> default of integers without overflow protection means that math involving 
>>> std::chrono is inherently more dangerous than math involving double.  This 
>>> is particularly bad when we use time to speak about timeouts.
>>> 
>>> Too many templates: std::chrono uses templates heavily.  It’s overkill for 
>>> measuring time.  This leads to verbosity and template creep throughout 
>>> common algorithms that take time as an argument.  For example if we use 
>>> doubles, a method for sleeping for a second might look like 
>>> sleepForSeconds(double).  This works even if someone wants to sleep for a 
>>> nanoseconds, since 0.01 is easy to represent using a double.  Also, 
>>> multiplying or dividing a double by a small constant factor (1,000,000,000 
>>> is small by double standards) is virtually guaranteed to avoid any loss of 
>>> precision.  But as soon as such a utility gets std::chronified, it becomes 
>>> a template.  This is because you cannot have 
>>> sleepFor(std::chrono::seconds), since that wouldn’t allow you to represent 
>>> fractions of seconds.  This brings me to my next point.
>>> 
>>> Overflow danger: std::chrono is based on integers and its math methods do 
>>> not support overflow protection.  This has led to serious bugs like 
>>> https://bugs.webkit.org/show_bug.cgi?id=157924 
>>> .  This cancels out the 
>>> “remember what unit is used” benefit cited above.  It’s true that I know 
>>> what type of time I have, but as soon as I duration_cast it to another 
>>> unit, I may overflow.  The type system does not help!  This is insane: 
>>> std::chrono requires you to do more work when writing multi-unit code, so 
>>> that you satisfy the type checker, but you still have to be just as 
>>> paranoid around multi-unit scenarios.  Forgetting that you have 
>>> milliseconds and using it as seconds is trivially fixable.  But if 
>>> std::chrono flags such an error and you fix it with a duration_cast (as any 
>>> std::chrono tutorial will tell you to do), you’ve just introduced an 
>>> unchecked overflow and such unchecked overflows are known to cause bugs 
>>> that 

Re: [webkit-dev] RFC: stop using std::chrono, go back to using doubles for time

2016-11-04 Thread Brent Fulgham
EWS Hates your patch! :-)

> On Nov 4, 2016, at 10:01 AM, Filip Pizlo  wrote:
> 
> Hi everyone!
> 
> That last time we talked about this, there seemed to be a lot of agreement 
> that we should go with the Seconds/MonotonicTime/WallTime approach.
> 
> I have implemented it: https://bugs.webkit.org/show_bug.cgi?id=152045 
> 
> 
> That patch just takes a subset of our time code - all of the stuff that 
> transitively touches ParkingLot - and converts it to use the new time 
> classes.  Reviews welcome!
> 
> -Filip
> 
> 
> 
>> On May 22, 2016, at 6:41 PM, Filip Pizlo > > wrote:
>> 
>> Hi everyone!
>> 
>> I’d like us to stop using std::chrono and go back to using doubles for time. 
>>  First I list the things that I think we wanted to get from std::chrono - 
>> the reasons why we started switching to it in the first place.  Then I list 
>> some disadvantages of std::chrono that we've seen from fixing 
>> std::chrono-based code.  Finally I propose some options for how to use 
>> doubles for time.
>> 
>> Why we switched to std::chrono
>> 
>> A year ago we started using std::chrono for measuring time.  std::chrono has 
>> a rich typesystem for expressing many different kinds of time.  For example, 
>> you can distinguish between an absolute point in time and a relative time.  
>> And you can distinguish between different units, like nanoseconds, 
>> milliseconds, etc.
>> 
>> Before this, we used doubles for time.  std::chrono’s advantages over 
>> doubles are:
>> 
>> Easy to remember what unit is used: We sometimes used doubles for 
>> milliseconds and sometimes for seconds.  std::chrono prevents you from 
>> getting the two confused.
>> 
>> Easy to remember what kind of clock is used: We sometimes use the monotonic 
>> clock and sometimes the wall clock (aka the real time clock).  Bad things 
>> would happen if we passed a time measured using the monotonic clock to 
>> functions that expected time measured using the wall clock, and vice-versa.  
>> I know that I’ve made this mistake in the past, and it can be painful to 
>> debug.
>> 
>> In short, std::chrono uses compile-time type checking to catch some bugs.
>> 
>> Disadvantages of using std::chrono
>> 
>> We’ve seen some problems with std::chrono, and I think that the problems 
>> outweigh the advantages.  std::chrono suffers from a heavily templatized API 
>> that results in template creep in our own internal APIs.  std::chrono’s 
>> default of integers without overflow protection means that math involving 
>> std::chrono is inherently more dangerous than math involving double.  This 
>> is particularly bad when we use time to speak about timeouts.
>> 
>> Too many templates: std::chrono uses templates heavily.  It’s overkill for 
>> measuring time.  This leads to verbosity and template creep throughout 
>> common algorithms that take time as an argument.  For example if we use 
>> doubles, a method for sleeping for a second might look like 
>> sleepForSeconds(double).  This works even if someone wants to sleep for a 
>> nanoseconds, since 0.01 is easy to represent using a double.  Also, 
>> multiplying or dividing a double by a small constant factor (1,000,000,000 
>> is small by double standards) is virtually guaranteed to avoid any loss of 
>> precision.  But as soon as such a utility gets std::chronified, it becomes a 
>> template.  This is because you cannot have sleepFor(std::chrono::seconds), 
>> since that wouldn’t allow you to represent fractions of seconds.  This 
>> brings me to my next point.
>> 
>> Overflow danger: std::chrono is based on integers and its math methods do 
>> not support overflow protection.  This has led to serious bugs like 
>> https://bugs.webkit.org/show_bug.cgi?id=157924 
>> .  This cancels out the 
>> “remember what unit is used” benefit cited above.  It’s true that I know 
>> what type of time I have, but as soon as I duration_cast it to another unit, 
>> I may overflow.  The type system does not help!  This is insane: std::chrono 
>> requires you to do more work when writing multi-unit code, so that you 
>> satisfy the type checker, but you still have to be just as paranoid around 
>> multi-unit scenarios.  Forgetting that you have milliseconds and using it as 
>> seconds is trivially fixable.  But if std::chrono flags such an error and 
>> you fix it with a duration_cast (as any std::chrono tutorial will tell you 
>> to do), you’ve just introduced an unchecked overflow and such unchecked 
>> overflows are known to cause bugs that manifest as pages not working 
>> correctly.
>> 
>> I think that doubles are better than std::chrono in multi-unit scenarios.  
>> It may be possible to have std::chrono work with doubles, but this probably 
>> implies us writing our own clocks.  std::chrono’s default clocks use 
>> integers, not doubles.  It also may be possible to 

Re: [webkit-dev] RFC: stop using std::chrono, go back to using doubles for time

2016-11-04 Thread Filip Pizlo
Hi everyone!

That last time we talked about this, there seemed to be a lot of agreement that 
we should go with the Seconds/MonotonicTime/WallTime approach.

I have implemented it: https://bugs.webkit.org/show_bug.cgi?id=152045

That patch just takes a subset of our time code - all of the stuff that 
transitively touches ParkingLot - and converts it to use the new time classes.  
Reviews welcome!

-Filip



> On May 22, 2016, at 6:41 PM, Filip Pizlo  wrote:
> 
> Hi everyone!
> 
> I’d like us to stop using std::chrono and go back to using doubles for time.  
> First I list the things that I think we wanted to get from std::chrono - the 
> reasons why we started switching to it in the first place.  Then I list some 
> disadvantages of std::chrono that we've seen from fixing std::chrono-based 
> code.  Finally I propose some options for how to use doubles for time.
> 
> Why we switched to std::chrono
> 
> A year ago we started using std::chrono for measuring time.  std::chrono has 
> a rich typesystem for expressing many different kinds of time.  For example, 
> you can distinguish between an absolute point in time and a relative time.  
> And you can distinguish between different units, like nanoseconds, 
> milliseconds, etc.
> 
> Before this, we used doubles for time.  std::chrono’s advantages over doubles 
> are:
> 
> Easy to remember what unit is used: We sometimes used doubles for 
> milliseconds and sometimes for seconds.  std::chrono prevents you from 
> getting the two confused.
> 
> Easy to remember what kind of clock is used: We sometimes use the monotonic 
> clock and sometimes the wall clock (aka the real time clock).  Bad things 
> would happen if we passed a time measured using the monotonic clock to 
> functions that expected time measured using the wall clock, and vice-versa.  
> I know that I’ve made this mistake in the past, and it can be painful to 
> debug.
> 
> In short, std::chrono uses compile-time type checking to catch some bugs.
> 
> Disadvantages of using std::chrono
> 
> We’ve seen some problems with std::chrono, and I think that the problems 
> outweigh the advantages.  std::chrono suffers from a heavily templatized API 
> that results in template creep in our own internal APIs.  std::chrono’s 
> default of integers without overflow protection means that math involving 
> std::chrono is inherently more dangerous than math involving double.  This is 
> particularly bad when we use time to speak about timeouts.
> 
> Too many templates: std::chrono uses templates heavily.  It’s overkill for 
> measuring time.  This leads to verbosity and template creep throughout common 
> algorithms that take time as an argument.  For example if we use doubles, a 
> method for sleeping for a second might look like sleepForSeconds(double).  
> This works even if someone wants to sleep for a nanoseconds, since 0.01 
> is easy to represent using a double.  Also, multiplying or dividing a double 
> by a small constant factor (1,000,000,000 is small by double standards) is 
> virtually guaranteed to avoid any loss of precision.  But as soon as such a 
> utility gets std::chronified, it becomes a template.  This is because you 
> cannot have sleepFor(std::chrono::seconds), since that wouldn’t allow you to 
> represent fractions of seconds.  This brings me to my next point.
> 
> Overflow danger: std::chrono is based on integers and its math methods do not 
> support overflow protection.  This has led to serious bugs like 
> https://bugs.webkit.org/show_bug.cgi?id=157924 
> .  This cancels out the 
> “remember what unit is used” benefit cited above.  It’s true that I know what 
> type of time I have, but as soon as I duration_cast it to another unit, I may 
> overflow.  The type system does not help!  This is insane: std::chrono 
> requires you to do more work when writing multi-unit code, so that you 
> satisfy the type checker, but you still have to be just as paranoid around 
> multi-unit scenarios.  Forgetting that you have milliseconds and using it as 
> seconds is trivially fixable.  But if std::chrono flags such an error and you 
> fix it with a duration_cast (as any std::chrono tutorial will tell you to 
> do), you’ve just introduced an unchecked overflow and such unchecked 
> overflows are known to cause bugs that manifest as pages not working 
> correctly.
> 
> I think that doubles are better than std::chrono in multi-unit scenarios.  It 
> may be possible to have std::chrono work with doubles, but this probably 
> implies us writing our own clocks.  std::chrono’s default clocks use 
> integers, not doubles.  It also may be possible to teach std::chrono to do 
> overflow protection, but that would make me so sad since using double means 
> not having to worry about overflow at all.
> 
> The overflow issue is interesting because of its implications for how we do 
> timeouts.  The way to have a method with an optional timeout is 

Re: [webkit-dev] RFC: stop using std::chrono, go back to using doubles for time

2016-05-23 Thread Geoffrey Garen
>> Can we go with “WallClock” and “MonotonicClock” instead of “WallTime” and 
>> “MonotonicTime"? Clock is a nice clear noun. Also, time is an illusion 
>> caused by parallax in the astral plane.
> 
> I think time is the right term. "3pm" is a "time", not a "clock". Also 42 
> seconds since monotonic epoch is a monotonic time, not a monotonic clock. 

Hmmm… I think I read your original proposal wrong.

Sure, Seconds, MonotonicTime and WallTime are all times.

Geoff
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-dev


Re: [webkit-dev] RFC: stop using std::chrono, go back to using doubles for time

2016-05-23 Thread Antti Koivisto
I think the actual issue here was that std::chrono::duration can't
represent infinite duration and some of our code has been hacking around
that with std::chrono::duration::max(). Clock time + duration is not going
to overflow if the duration is natural (a finite constant or produced by
diffing time_points).

I have found that using Optional in cases where
the duration legitimately can be unspecified/infinite works well. In most
cases it can't be.

If we decide to write our own time type system lets make sure it covers all
the existing use of std::chrono without losing any of the static typing.
But maybe simply disallowing std::chrono::duration::max() in the style
checker would solve the immediate problem here?


   antti


On Mon, May 23, 2016 at 4:41 AM, Filip Pizlo  wrote:

> Hi everyone!
>
> I’d like us to stop using std::chrono and go back to using doubles for
> time.  First I list the things that I think we wanted to get from
> std::chrono - the reasons why we started switching to it in the first
> place.  Then I list some disadvantages of std::chrono that we've seen from
> fixing std::chrono-based code.  Finally I propose some options for how to
> use doubles for time.
>
> *Why we switched to std::chrono*
>
> A year ago we started using std::chrono for measuring time.  std::chrono
> has a rich typesystem for expressing many different kinds of time.  For
> example, you can distinguish between an absolute point in time and a
> relative time.  And you can distinguish between different units, like
> nanoseconds, milliseconds, etc.
>
> Before this, we used doubles for time.  std::chrono’s advantages over
> doubles are:
>
> *Easy to remember what unit is used:* We sometimes used doubles for
> milliseconds and sometimes for seconds.  std::chrono prevents you from
> getting the two confused.
>
> *Easy to remember what kind of clock is used:* We sometimes use the
> monotonic clock and sometimes the wall clock (aka the real time clock).
> Bad things would happen if we passed a time measured using the monotonic
> clock to functions that expected time measured using the wall clock, and
> vice-versa.  I know that I’ve made this mistake in the past, and it can be
> painful to debug.
>
> In short, std::chrono uses compile-time type checking to catch some bugs.
>
> *Disadvantages of using std::chrono*
>
> We’ve seen some problems with std::chrono, and I think that the problems
> outweigh the advantages.  std::chrono suffers from a heavily templatized
> API that results in template creep in our own internal APIs.  std::chrono’s
> default of integers without overflow protection means that math involving
> std::chrono is inherently more dangerous than math involving double.  This
> is particularly bad when we use time to speak about timeouts.
>
> *Too many templates:* std::chrono uses templates heavily.  It’s overkill
> for measuring time.  This leads to verbosity and template creep throughout
> common algorithms that take time as an argument.  For example if we use
> doubles, a method for sleeping for a second might look like
> sleepForSeconds(double).  This works even if someone wants to sleep for a
> nanoseconds, since 0.01 is easy to represent using a double.  Also,
> multiplying or dividing a double by a small constant factor (1,000,000,000
> is small by double standards) is virtually guaranteed to avoid any loss of
> precision.  But as soon as such a utility gets std::chronified, it becomes
> a template.  This is because you cannot have
> sleepFor(std::chrono::seconds), since that wouldn’t allow you to represent
> fractions of seconds.  This brings me to my next point.
>
> *Overflow danger:* std::chrono is based on integers and its math methods
> do not support overflow protection.  This has led to serious bugs like
> https://bugs.webkit.org/show_bug.cgi?id=157924.  This cancels out the
> “remember what unit is used” benefit cited above.  It’s true that I know
> what type of time I have, but as soon as I duration_cast it to another
> unit, I may overflow.  The type system does not help!  This is insane:
> std::chrono requires you to do more work when writing multi-unit code, so
> that you satisfy the type checker, but you still have to be just as
> paranoid around multi-unit scenarios.  Forgetting that you have
> milliseconds and using it as seconds is trivially fixable.  But if
> std::chrono flags such an error and you fix it with a duration_cast (as any
> std::chrono tutorial will tell you to do), you’ve just introduced an
> unchecked overflow and such unchecked overflows are known to cause bugs
> that manifest as pages not working correctly.
>
> I think that doubles are better than std::chrono in multi-unit scenarios.
> It may be possible to have std::chrono work with doubles, but this probably
> implies us writing our own clocks.  std::chrono’s default clocks use
> integers, not doubles.  It also may be possible to teach std::chrono to do
> overflow protection, but that would make me 

Re: [webkit-dev] RFC: stop using std::chrono, go back to using doubles for time

2016-05-23 Thread Filip Pizlo


On May 23, 2016, at 11:16 AM, Geoffrey Garen  wrote:

>> 3 - There exists a solution - non-templated custom classes - that removes 
>> both classes of subtle bugs, without the template creep.
> 
> Hard to argue with this.
> 
> Can we go with “WallClock” and “MonotonicClock” instead of “WallTime” and 
> “MonotonicTime"? Clock is a nice clear noun. Also, time is an illusion caused 
> by parallax in the astral plane.

I think time is the right term. "3pm" is a "time", not a "clock". Also 42 
seconds since monotonic epoch is a monotonic time, not a monotonic clock. 

> 
> Geoff
> 
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-dev


Re: [webkit-dev] RFC: stop using std::chrono, go back to using doubles for time

2016-05-23 Thread Geoffrey Garen
> 3 - There exists a solution - non-templated custom classes - that removes 
> both classes of subtle bugs, without the template creep.

Hard to argue with this.

Can we go with “WallClock” and “MonotonicClock” instead of “WallTime” and 
“MonotonicTime"? Clock is a nice clear noun. Also, time is an illusion caused 
by parallax in the astral plane.

Geoff

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-dev


Re: [webkit-dev] RFC: stop using std::chrono, go back to using doubles for time

2016-05-23 Thread Geoffrey Garen
Since double is not a user-defined type, my understanding is that your template 
specializations in the std namespace are undefined behavior.

Geoff

> On May 22, 2016, at 10:46 PM, Michal Debski <m.deb...@samsung.com> wrote:
> 
> Hi,
>  
> sorry but this really bugs me. Isn't this enough?
>  
> namespace WTF {
> 
> using nanoseconds = std::chrono::duration<double, std::nano>;
> using microseconds = std::chrono::duration<double, std::micro>;
> using milliseconds = std::chrono::duration<double, std::milli>;
> using seconds = std::chrono::duration;
> using minutes = std::chrono::duration<double, std::ratio<60>>;
> using hours = std::chrono::duration<double, std::ratio<3600>>;
> 
> template 
> std::chrono::time_point<Clock, seconds> now()
> {
> return Clock::now();
> }
> 
> }
>  
> and forbid using std::chrono::clock::now()/durations with check-style. It 
> seems like the best of both worlds. Oh and the infinity:
>  
> namespace std {
> namespace chrono {
> 
> template<>
> struct duration_values {
> static constexpr double min() { return 
> -std::numeric_limits::infinity(); }
> static constexpr double zero() { return .0; }
> static constexpr double max() { return 
> std::numeric_limits::infinity(); }
> };
> 
> }
> }
>  
> Best regards,
> Michal Debski
>  
> --- Original Message ---
> Sender : Filip Pizlo<fpi...@apple.com <mailto:fpi...@apple.com>>
> Date : May 23, 2016 02:41 (GMT+01:00)
> Title : [webkit-dev] RFC: stop using std::chrono, go back to using doubles 
> for time
>  
> Hi everyone! 
> 
> I’d like us to stop using std::chrono and go back to using doubles for time.  
> First I list the things that I think we wanted to get from std::chrono - the 
> reasons why we started switching to it in the first place.  Then I list some 
> disadvantages of std::chrono that we've seen from fixing std::chrono-based 
> code.  Finally I propose some options for how to use doubles for time.
> 
> Why we switched to std::chrono
> 
> A year ago we started using std::chrono for measuring time.  std::chrono has 
> a rich typesystem for expressing many different kinds of time.  For example, 
> you can distinguish between an absolute point in time and a relative time.  
> And you can distinguish between different units, like nanoseconds, 
> milliseconds, etc.
> 
> Before this, we used doubles for time.  std::chrono’s advantages over doubles 
> are:
> 
> Easy to remember what unit is used: We sometimes used doubles for 
> milliseconds and sometimes for seconds.  std::chrono prevents you from 
> getting the two confused.
> 
> Easy to remember what kind of clock is used: We sometimes use the monotonic 
> clock and sometimes the wall clock (aka the real time clock).  Bad things 
> would happen if we passed a time measured using the monotonic clock to 
> functions that expected time measured using the wall clock, and vice-versa.  
> I know that I’ve made this mistake in the past, and it can be painful to 
> debug.
> 
> In short, std::chrono uses compile-time type checking to catch some bugs.
> 
> Disadvantages of using std::chrono
> 
> We’ve seen some problems with std::chrono, and I think that the problems 
> outweigh the advantages.  std::chrono suffers from a heavily templatized API 
> that results in template creep in our own internal APIs.  std::chrono’s 
> default of integers without overflow protection means that math involving 
> std::chrono is inherently more dangerous than math involving double.  This is 
> particularly bad when we use time to speak about timeouts.
> 
> Too many templates: std::chrono uses templates heavily.  It’s overkill for 
> measuring time.  This leads to verbosity and template creep throughout common 
> algorithms that take time as an argument.  For example if we use doubles, a 
> method for sleeping for a second might look like sleepForSeconds(double).  
> This works even if someone wants to sleep for a nanoseconds, since 0.01 
> is easy to represent using a double.  Also, multiplying or dividing a double 
> by a small constant factor (1,000,000,000 is small by double standards) is 
> virtually guaranteed to avoid any loss of precision.  But as soon as such a 
> utility gets std::chronified, it becomes a template.  This is because you 
> cannot have sleepFor(std::chrono::seconds), since that wouldn’t allow you to 
> represent fractions of seconds.  This brings me to my next point.
> 
> Overflow danger: std::chrono is based on integers and its math methods do not 
> support overflow protection.  This has led to serious bugs like 
> https://bugs.webkit.org/show_bug.cgi?id=157924 
>

Re: [webkit-dev] RFC: stop using std::chrono, go back to using doubles for time

2016-05-23 Thread Brian Burg
+1 to Michael’s point. Naming of variables holding seconds/milliseconds is all 
over the place.
So, I would favor using Seconds/WallTime/MonotonicTime classes, since they will 
basically
guarantee that the variable name and/or type will describe the units near 
use-sites and avoid
ambiguity.

Not to belabor Fil’s original argument against std::chrono, but the sheer 
amount of templates
necessary to express something very simple has scared away myself and plenty of 
others
from converting code away from doubles. Not to mention, it will trip up anyone 
reading the
code who hasn’t invested time reading the documentation or doing their own 
conversion.
Some of the errors Fil mentions, such as overflow, are so obfuscated by the 
type gymnastics
that the easy-to-understand class of bugs std::chrono eliminates are replaced 
with more
subtle and harder to fix overflow errors.

Brian

> On May 23, 2016, at 8:04 AM, Michael Catanzaro  wrote:
> 
> On Mon, 2016-05-23 at 07:27 -0700, Filip Pizło wrote:
>> You guys are making a convincing case for
>> Seconds/WallTime/MonotonicTime!
>> 
>> -Filip
> 
> I will add: the convention "double means seconds" is very much not
> obvious. It's OK when we're careful to consistently use "seconds" in
> function and variable names, but in practice, that's not always or even
> usually the case in WebKit code.
> ___
> webkit-dev mailing list
> webkit-dev@lists.webkit.org
> https://lists.webkit.org/mailman/listinfo/webkit-dev

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-dev


Re: [webkit-dev] RFC: stop using std::chrono, go back to using doubles for time

2016-05-23 Thread Michael Catanzaro
On Mon, 2016-05-23 at 07:27 -0700, Filip Pizło wrote:
> You guys are making a convincing case for
> Seconds/WallTime/MonotonicTime!
> 
> -Filip

I will add: the convention "double means seconds" is very much not
obvious. It's OK when we're careful to consistently use "seconds" in
function and variable names, but in practice, that's not always or even
usually the case in WebKit code.
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-dev


Re: [webkit-dev] RFC: stop using std::chrono, go back to using doubles for time

2016-05-23 Thread Filip Pizło
You guys are making a convincing case for Seconds/WallTime/MonotonicTime!

-Filip

> On May 22, 2016, at 11:19 PM, Ryosuke Niwa  wrote:
> 
> I'm with Brady here.  In WebCore, there are enough DOM and network
> APIs that mix wall time and monotonically increasing time (e.g. there
> has been proposals to use monodically increasing time in
> event.prototype.timeStamp even though various event related code
> relies on it being a wall clock time) that having a type system would
> be helpful.
> - R. Niwa
> 
> 
>> On Sun, May 22, 2016 at 10:47 PM, Brady Eidson  wrote:
>> 
>> On May 22, 2016, at 6:41 PM, Filip Pizlo  wrote:
>> 
>> Hi everyone!
>> 
>> I’d like us to stop using std::chrono and go back to using doubles for time.
>> First I list the things that I think we wanted to get from std::chrono - the
>> reasons why we started switching to it in the first place.  Then I list some
>> disadvantages of std::chrono that we've seen from fixing std::chrono-based
>> code.  Finally I propose some options for how to use doubles for time.
>> 
>> Why we switched to std::chrono
>> 
>> A year ago we started using std::chrono for measuring time.  std::chrono has
>> a rich typesystem for expressing many different kinds of time.  For example,
>> you can distinguish between an absolute point in time and a relative time.
>> And you can distinguish between different units, like nanoseconds,
>> milliseconds, etc.
>> 
>> Before this, we used doubles for time.  std::chrono’s advantages over
>> doubles are:
>> 
>> Easy to remember what unit is used: We sometimes used doubles for
>> milliseconds and sometimes for seconds.  std::chrono prevents you from
>> getting the two confused.
>> 
>> Easy to remember what kind of clock is used: We sometimes use the monotonic
>> clock and sometimes the wall clock (aka the real time clock).  Bad things
>> would happen if we passed a time measured using the monotonic clock to
>> functions that expected time measured using the wall clock, and vice-versa.
>> I know that I’ve made this mistake in the past, and it can be painful to
>> debug.
>> 
>> In short, std::chrono uses compile-time type checking to catch some bugs.
>> 
>> Disadvantages of using std::chrono
>> 
>> We’ve seen some problems with std::chrono, and I think that the problems
>> outweigh the advantages.  std::chrono suffers from a heavily templatized API
>> that results in template creep in our own internal APIs.  std::chrono’s
>> default of integers without overflow protection means that math involving
>> std::chrono is inherently more dangerous than math involving double.  This
>> is particularly bad when we use time to speak about timeouts.
>> 
>> Too many templates: std::chrono uses templates heavily.  It’s overkill for
>> measuring time.  This leads to verbosity and template creep throughout
>> common algorithms that take time as an argument.  For example if we use
>> doubles, a method for sleeping for a second might look like
>> sleepForSeconds(double).  This works even if someone wants to sleep for a
>> nanoseconds, since 0.01 is easy to represent using a double.  Also,
>> multiplying or dividing a double by a small constant factor (1,000,000,000
>> is small by double standards) is virtually guaranteed to avoid any loss of
>> precision.  But as soon as such a utility gets std::chronified, it becomes a
>> template.  This is because you cannot have sleepFor(std::chrono::seconds),
>> since that wouldn’t allow you to represent fractions of seconds.  This
>> brings me to my next point.
>> 
>> Overflow danger: std::chrono is based on integers and its math methods do
>> not support overflow protection.  This has led to serious bugs like
>> https://bugs.webkit.org/show_bug.cgi?id=157924.  This cancels out the
>> “remember what unit is used” benefit cited above.  It’s true that I know
>> what type of time I have, but as soon as I duration_cast it to another unit,
>> I may overflow.  The type system does not help!  This is insane: std::chrono
>> requires you to do more work when writing multi-unit code, so that you
>> satisfy the type checker, but you still have to be just as paranoid around
>> multi-unit scenarios.  Forgetting that you have milliseconds and using it as
>> seconds is trivially fixable.  But if std::chrono flags such an error and
>> you fix it with a duration_cast (as any std::chrono tutorial will tell you
>> to do), you’ve just introduced an unchecked overflow and such unchecked
>> overflows are known to cause bugs that manifest as pages not working
>> correctly.
>> 
>> I think that doubles are better than std::chrono in multi-unit scenarios.
>> It may be possible to have std::chrono work with doubles, but this probably
>> implies us writing our own clocks.  std::chrono’s default clocks use
>> integers, not doubles.  It also may be possible to teach std::chrono to do
>> overflow protection, but that would make me so sad since using double means
>> not having to worry 

Re: [webkit-dev] RFC: stop using std::chrono, go back to using doubles for time

2016-05-23 Thread Filip Pizło




-Filip
> On May 23, 2016, at 12:12 AM, Michal Debski <m.deb...@samsung.com> wrote:
> 
> Please this example: http://ideone.com/c640Xd
> 
I'm not going to write "WTF::now()" every time I 
want the time. That's awful!

One of the problems with chrono is the use of awkward templates throughout the 
API. Your solution makes this worse. 
> From cppreference:
> 
> "(time_point) is implemented as if it stores a value of typeDuration 
> indicating the time interval from the start of the Clock's epoch."
> 
> "If Rep is floating point, then the duration can represent fractions of 
> ticks."
> 
> http://en.cppreference.com/w/cpp/chrono/time_point
> 
> http://en.cppreference.com/w/cpp/chrono/duration
> 
>  
> 
> time_point still remembers which clock it belongs to, see the specialization 
> now() returns.  
> 
> The only problem I see is that conversion from fractional duration with 
> Infinite value to integer duration is undefined. But I assume it would be 
> forbiden to use integer based chrono altogether.
> 
That seems like a tough thing to guarantee.
> As for the last point I don't understand what do you mean by non-canonical.
> 
According to Merriam-Webster, canonical means: conforming to a general rule or 
acceptable procedure. I don't think that your approach is the normal, generally 
accepted way to use std::chrono. 
> It uses the API as intended, why would c++ expose the templates if not for 
> specializing the behaviour? Also move operator is not canonical in WTF 
> strictly speaking.
> 
>  
> 
> I just remember about ugly bugs in MediaTime arithmetics.
> 
>  
> 
> Best regards,
> 
> Michal Debski
> 
>  
> 
> --- Original Message ---
> 
> Sender : Filip Pizlo<fpi...@apple.com>
> 
> Date : May 23, 2016 07:32 (GMT+01:00)
> 
> Title : Re: [webkit-dev] RFC: stop using std::chrono, go back to using 
> doubles for time
> 
>  
> 
> 
> 
>> On May 22, 2016, at 10:46 PM, Michal Debski <m.deb...@samsung.com> wrote:
>> 
>> Hi,
>> 
>>  
>> 
>> sorry but this really bugs me. Isn't this enough?
>> 
>>  
>> 
>> namespace WTF {
>> 
>> using nanoseconds = std::chrono::duration<double, std::nano>;
>> using microseconds = std::chrono::duration<double, std::micro>;
>> using milliseconds = std::chrono::duration<double, std::milli>;
>> using seconds = std::chrono::duration;
>> using minutes = std::chrono::duration<double, std::ratio<60>>;
>> using hours = std::chrono::duration<double, std::ratio<3600>>;
>> 
>> 
>> template 
>> std::chrono::time_point<Clock, seconds> now()
>> {
>> return Clock::now();
>> }
>> 
> Can you clarify how this returns fractional seconds?
> 
> Note that your code snippets are not enough to cover WebKit's use of clocks. 
> For example we would need wall clock and monotonic clock classes with 
> time_point types. If we have to significantly customize std::chrono and 
> forbid some but not all of its API, then probably the total amount of code to 
> do this would be comparable to writing our own Seconds/WallTime/MonotonicTime 
> classes.
>> 
>> }
>> 
>>  
>> 
>> and forbid using std::chrono::clock::now()/durations with check-style. It 
>> seems like the best of both worlds.
>> 
> It's an interesting perspective. But I would find it confusing if we used a 
> non-canonical kind of std::chrono. And I'm not convinced that the changes 
> required to make this work are as simple as what you say. 
>> Oh and the infinity:
>> 
>>  
>> 
>> namespace std {
>> namespace chrono {
>> 
>> template<>
>> struct duration_values {
>> static constexpr double min() { return 
>> -std::numeric_limits::infinity(); }
>> static constexpr double zero() { return .0; }
>> static constexpr double max() { return 
>> std::numeric_limits::infinity(); }
>> };
>> 
>> }
>> } 
>> 
>> Best regards,
>> Michal Debski
>> 
>>  
>> 
>> --- Original Message ---
>> 
>> Sender : Filip Pizlo<fpi...@apple.com>
>> 
>> Date : May 23, 2016 02:41 (GMT+01:00)
>> 
>> Title : [webkit-dev] RFC: stop using std::chrono, go back to using doubles 
>> for time
>> 
>>  
>> 
>> Hi everyone!
>> 
>> I’d like us to stop using std::chrono and go back to using doubles for time. 
>>  First I list the things that I think we wanted to get from std::chrono - 
>> the reasons why we starte

Re: [webkit-dev] RFC: stop using std::chrono, go back to using doubles for time

2016-05-23 Thread Michal Debski






Please this example: http://ideone.com/c640Xd
From cppreference:
"(time_point) is implemented as if it stores a value of typeDuration indicating the time interval from the start of the Clock's epoch."
"If Rep is floating point, then the duration can represent fractions of ticks."
http://en.cppreference.com/w/cpp/chrono/time_point
http://en.cppreference.com/w/cpp/chrono/duration
 
time_point still remembers which clock it belongs to, see the specialization now() returns.
 
The only problem I see is that conversion from fractional duration with Infinite value to integer duration is undefined. But I assume it would be forbiden to use integer based chrono altogether. As for the last point I don't understand what do you mean by non-canonical. It uses the API as intended, why would c++ expose the templates if not for specializing the behaviour? Also move operator is not canonical in WTF strictly speaking.
 
I just remember about ugly bugs in MediaTime arithmetics.
 
Best regards,
Michal Debski
 
--- Original Message ---
Sender : Filip Pizlo<fpi...@apple.com>
Date : May 23, 2016 07:32 (GMT+01:00)
Title : Re: [webkit-dev] RFC: stop using std::chrono, go back to using doubles for time
 


On May 22, 2016, at 10:46 PM, Michal Debski <m.deb...@samsung.com> wrote:









Hi,
 
sorry but this really bugs me. Isn't this enough?
 
namespace WTF {using nanoseconds = std::chrono::duration<double, std::nano>;using microseconds = std::chrono::duration<double, std::micro>;using milliseconds = std::chrono::duration<double, std::milli>;using seconds = std::chrono::duration;using minutes = std::chrono::duration<double, std::ratio<60>>;using hours = std::chrono::duration<double, std::ratio<3600>>;
template std::chrono::time_point<Clock, seconds> now(){    return Clock::now();}
Can you clarify how this returns fractional seconds?

Note that your code snippets are not enough to cover WebKit's use of clocks. For example we would need wall clock and monotonic clock classes with time_point types. If we have to significantly customize std::chrono and forbid some but not all of its API, then probably the total amount of code to do this would be comparable to writing our own Seconds/WallTime/MonotonicTime classes.


}
 
and forbid using std::chrono::clock::now()/durations with check-style. It seems like the best of both worlds. 
It's an interesting perspective. But I would find it confusing if we used a non-canonical kind of std::chrono. And I'm not convinced that the changes required to make this work are as simple as what you say. 


Oh and the infinity:
 
namespace std {namespace chrono {template<>struct duration_values {    static constexpr double min() { return -std::numeric_limits::infinity(); }    static constexpr double zero() { return .0; }    static constexpr double max() { return std::numeric_limits::infinity(); }};}} 

Best regards,Michal Debski
 
--- Original Message ---
Sender : Filip Pizlo<fpi...@apple.com>
Date : May 23, 2016 02:41 (GMT+01:00)
Title : [webkit-dev] RFC: stop using std::chrono, go back to using doubles for time
 

Hi everyone! 

I’d like us to stop using std::chrono and go back to using doubles for time.  First I list the things that I think we wanted to get from std::chrono - the reasons why we started switching to it in the first place.  Then I list some disadvantages of std::chrono that we've seen from fixing std::chrono-based code.  Finally I propose some options for how to use doubles for time.

Why we switched to std::chrono

A year ago we started using std::chrono for measuring time.  std::chrono has a rich typesystem for expressing many different kinds of time.  For example, you can distinguish between an absolute point in time and a relative time.  And you can distinguish between different units, like nanoseconds, milliseconds, etc.

Before this, we used doubles for time.  std::chrono’s advantages over doubles are:

Easy to remember what unit is used: We sometimes used doubles for milliseconds and sometimes for seconds.  std::chrono prevents you from getting the two confused.

Easy to remember what kind of clock is used: We sometimes use the monotonic clock and sometimes the wall clock (aka the real time clock).  Bad things would happen if we passed a time measured using the monotonic clock to functions that expected time measured using the wall clock, and vice-versa.  I know that I’ve made this mistake in the past, and it can be painful to debug.

In short, std::chrono uses compile-time type checking to catch some bugs.

Disadvantages of using std::chrono

We’ve seen some problems with std::chrono, and I think that the problems outweigh the advantages.  std::chrono suffers from a heavily templatized API that results in template creep in our own internal APIs.  std::chrono’s default of integers wi

Re: [webkit-dev] RFC: stop using std::chrono, go back to using doubles for time

2016-05-23 Thread Filip Pizlo


> On May 22, 2016, at 10:46 PM, Michal Debski <m.deb...@samsung.com> wrote:
> 
> Hi,
> 
>  
> 
> sorry but this really bugs me. Isn't this enough?
> 
>  
> 
> namespace WTF {
> 
> using nanoseconds = std::chrono::duration<double, std::nano>;
> using microseconds = std::chrono::duration<double, std::micro>;
> using milliseconds = std::chrono::duration<double, std::milli>;
> using seconds = std::chrono::duration;
> using minutes = std::chrono::duration<double, std::ratio<60>>;
> using hours = std::chrono::duration<double, std::ratio<3600>>;
> 
> 
> template 
> std::chrono::time_point<Clock, seconds> now()
> {
> return Clock::now();
> }
> 
Can you clarify how this returns fractional seconds?

Note that your code snippets are not enough to cover WebKit's use of clocks. 
For example we would need wall clock and monotonic clock classes with 
time_point types. If we have to significantly customize std::chrono and forbid 
some but not all of its API, then probably the total amount of code to do this 
would be comparable to writing our own Seconds/WallTime/MonotonicTime classes.
> 
> }
> 
>  
> 
> and forbid using std::chrono::clock::now()/durations with check-style. It 
> seems like the best of both worlds.
> 
It's an interesting perspective. But I would find it confusing if we used a 
non-canonical kind of std::chrono. And I'm not convinced that the changes 
required to make this work are as simple as what you say. 
> Oh and the infinity:
> 
>  
> 
> namespace std {
> namespace chrono {
> 
> template<>
> struct duration_values {
> static constexpr double min() { return 
> -std::numeric_limits::infinity(); }
> static constexpr double zero() { return .0; }
> static constexpr double max() { return 
> std::numeric_limits::infinity(); }
> };
> 
> }
> } 
> 
> Best regards,
> Michal Debski
> 
>  
> 
> --- Original Message ---
> 
> Sender : Filip Pizlo<fpi...@apple.com>
> 
> Date : May 23, 2016 02:41 (GMT+01:00)
> 
> Title : [webkit-dev] RFC: stop using std::chrono, go back to using doubles 
> for time
> 
>  
> 
> Hi everyone!
> 
> I’d like us to stop using std::chrono and go back to using doubles for time.  
> First I list the things that I think we wanted to get from std::chrono - the 
> reasons why we started switching to it in the first place.  Then I list some 
> disadvantages of std::chrono that we've seen from fixing std::chrono-based 
> code.  Finally I propose some options for how to use doubles for time.
> 
> Why we switched to std::chrono
> 
> A year ago we started using std::chrono for measuring time.  std::chrono has 
> a rich typesystem for expressing many different kinds of time.  For example, 
> you can distinguish between an absolute point in time and a relative time.  
> And you can distinguish between different units, like nanoseconds, 
> milliseconds, etc.
> 
> Before this, we used doubles for time.  std::chrono’s advantages over doubles 
> are:
> 
> Easy to remember what unit is used: We sometimes used doubles for 
> milliseconds and sometimes for seconds.  std::chrono prevents you from 
> getting the two confused.
> 
> Easy to remember what kind of clock is used: We sometimes use the monotonic 
> clock and sometimes the wall clock (aka the real time clock).  Bad things 
> would happen if we passed a time measured using the monotonic clock to 
> functions that expected time measured using the wall clock, and vice-versa.  
> I know that I’ve made this mistake in the past, and it can be painful to 
> debug.
> 
> In short, std::chrono uses compile-time type checking to catch some bugs.
> 
> Disadvantages of using std::chrono
> 
> We’ve seen some problems with std::chrono, and I think that the problems 
> outweigh the advantages.  std::chrono suffers from a heavily templatized API 
> that results in template creep in our own internal APIs.  std::chrono’s 
> default of integers without overflow protection means that math involving 
> std::chrono is inherently more dangerous than math involving double.  This is 
> particularly bad when we use time to speak about timeouts.
> 
> Too many templates: std::chrono uses templates heavily.  It’s overkill for 
> measuring time.  This leads to verbosity and template creep throughout common 
> algorithms that take time as an argument.  For example if we use doubles, a 
> method for sleeping for a second might look like sleepForSeconds(double).  
> This works even if someone wants to sleep for a nanoseconds, since 0.01 
> is easy to represent using a double.  Also, multiplying or dividing a double 
> by a small constant facto

Re: [webkit-dev] RFC: stop using std::chrono, go back to using doubles for time

2016-05-23 Thread Ryosuke Niwa
I'm with Brady here.  In WebCore, there are enough DOM and network
APIs that mix wall time and monotonically increasing time (e.g. there
has been proposals to use monodically increasing time in
event.prototype.timeStamp even though various event related code
relies on it being a wall clock time) that having a type system would
be helpful.
- R. Niwa


On Sun, May 22, 2016 at 10:47 PM, Brady Eidson  wrote:
>
> On May 22, 2016, at 6:41 PM, Filip Pizlo  wrote:
>
> Hi everyone!
>
> I’d like us to stop using std::chrono and go back to using doubles for time.
> First I list the things that I think we wanted to get from std::chrono - the
> reasons why we started switching to it in the first place.  Then I list some
> disadvantages of std::chrono that we've seen from fixing std::chrono-based
> code.  Finally I propose some options for how to use doubles for time.
>
> Why we switched to std::chrono
>
> A year ago we started using std::chrono for measuring time.  std::chrono has
> a rich typesystem for expressing many different kinds of time.  For example,
> you can distinguish between an absolute point in time and a relative time.
> And you can distinguish between different units, like nanoseconds,
> milliseconds, etc.
>
> Before this, we used doubles for time.  std::chrono’s advantages over
> doubles are:
>
> Easy to remember what unit is used: We sometimes used doubles for
> milliseconds and sometimes for seconds.  std::chrono prevents you from
> getting the two confused.
>
> Easy to remember what kind of clock is used: We sometimes use the monotonic
> clock and sometimes the wall clock (aka the real time clock).  Bad things
> would happen if we passed a time measured using the monotonic clock to
> functions that expected time measured using the wall clock, and vice-versa.
> I know that I’ve made this mistake in the past, and it can be painful to
> debug.
>
> In short, std::chrono uses compile-time type checking to catch some bugs.
>
> Disadvantages of using std::chrono
>
> We’ve seen some problems with std::chrono, and I think that the problems
> outweigh the advantages.  std::chrono suffers from a heavily templatized API
> that results in template creep in our own internal APIs.  std::chrono’s
> default of integers without overflow protection means that math involving
> std::chrono is inherently more dangerous than math involving double.  This
> is particularly bad when we use time to speak about timeouts.
>
> Too many templates: std::chrono uses templates heavily.  It’s overkill for
> measuring time.  This leads to verbosity and template creep throughout
> common algorithms that take time as an argument.  For example if we use
> doubles, a method for sleeping for a second might look like
> sleepForSeconds(double).  This works even if someone wants to sleep for a
> nanoseconds, since 0.01 is easy to represent using a double.  Also,
> multiplying or dividing a double by a small constant factor (1,000,000,000
> is small by double standards) is virtually guaranteed to avoid any loss of
> precision.  But as soon as such a utility gets std::chronified, it becomes a
> template.  This is because you cannot have sleepFor(std::chrono::seconds),
> since that wouldn’t allow you to represent fractions of seconds.  This
> brings me to my next point.
>
> Overflow danger: std::chrono is based on integers and its math methods do
> not support overflow protection.  This has led to serious bugs like
> https://bugs.webkit.org/show_bug.cgi?id=157924.  This cancels out the
> “remember what unit is used” benefit cited above.  It’s true that I know
> what type of time I have, but as soon as I duration_cast it to another unit,
> I may overflow.  The type system does not help!  This is insane: std::chrono
> requires you to do more work when writing multi-unit code, so that you
> satisfy the type checker, but you still have to be just as paranoid around
> multi-unit scenarios.  Forgetting that you have milliseconds and using it as
> seconds is trivially fixable.  But if std::chrono flags such an error and
> you fix it with a duration_cast (as any std::chrono tutorial will tell you
> to do), you’ve just introduced an unchecked overflow and such unchecked
> overflows are known to cause bugs that manifest as pages not working
> correctly.
>
> I think that doubles are better than std::chrono in multi-unit scenarios.
> It may be possible to have std::chrono work with doubles, but this probably
> implies us writing our own clocks.  std::chrono’s default clocks use
> integers, not doubles.  It also may be possible to teach std::chrono to do
> overflow protection, but that would make me so sad since using double means
> not having to worry about overflow at all.
>
> The overflow issue is interesting because of its implications for how we do
> timeouts.  The way to have a method with an optional timeout is to do one of
> these things:
>
> - Use 0 to mean no timeout.
> - Have one function for timeout and 

Re: [webkit-dev] RFC: stop using std::chrono, go back to using doubles for time

2016-05-22 Thread Michal Debski






Hi,
 
sorry but this really bugs me. Isn't this enough?
 
namespace WTF {using nanoseconds = std::chrono::duration<double, std::nano>;using microseconds = std::chrono::duration<double, std::micro>;using milliseconds = std::chrono::duration<double, std::milli>;using seconds = std::chrono::duration;using minutes = std::chrono::duration<double, std::ratio<60>>;using hours = std::chrono::duration<double, std::ratio<3600>>;
template std::chrono::time_point<Clock, seconds> now(){    return Clock::now();}}
 
and forbid using std::chrono::clock::now()/durations with check-style. It seems like the best of both worlds. Oh and the infinity:
 
namespace std {namespace chrono {template<>struct duration_values {    static constexpr double min() { return -std::numeric_limits::infinity(); }    static constexpr double zero() { return .0; }    static constexpr double max() { return std::numeric_limits::infinity(); }};}}
 
Best regards,Michal Debski
 
--- Original Message ---
Sender : Filip Pizlo<fpi...@apple.com>
Date : May 23, 2016 02:41 (GMT+01:00)
Title : [webkit-dev] RFC: stop using std::chrono, go back to using doubles for time
 

Hi everyone! 

I’d like us to stop using std::chrono and go back to using doubles for time.  First I list the things that I think we wanted to get from std::chrono - the reasons why we started switching to it in the first place.  Then I list some disadvantages of std::chrono that we've seen from fixing std::chrono-based code.  Finally I propose some options for how to use doubles for time.

Why we switched to std::chrono

A year ago we started using std::chrono for measuring time.  std::chrono has a rich typesystem for expressing many different kinds of time.  For example, you can distinguish between an absolute point in time and a relative time.  And you can distinguish between different units, like nanoseconds, milliseconds, etc.

Before this, we used doubles for time.  std::chrono’s advantages over doubles are:

Easy to remember what unit is used: We sometimes used doubles for milliseconds and sometimes for seconds.  std::chrono prevents you from getting the two confused.

Easy to remember what kind of clock is used: We sometimes use the monotonic clock and sometimes the wall clock (aka the real time clock).  Bad things would happen if we passed a time measured using the monotonic clock to functions that expected time measured using the wall clock, and vice-versa.  I know that I’ve made this mistake in the past, and it can be painful to debug.

In short, std::chrono uses compile-time type checking to catch some bugs.

Disadvantages of using std::chrono

We’ve seen some problems with std::chrono, and I think that the problems outweigh the advantages.  std::chrono suffers from a heavily templatized API that results in template creep in our own internal APIs.  std::chrono’s default of integers without overflow protection means that math involving std::chrono is inherently more dangerous than math involving double.  This is particularly bad when we use time to speak about timeouts.

Too many templates: std::chrono uses templates heavily.  It’s overkill for measuring time.  This leads to verbosity and template creep throughout common algorithms that take time as an argument.  For example if we use doubles, a method for sleeping for a second might look like sleepForSeconds(double).  This works even if someone wants to sleep for a nanoseconds, since 0.01 is easy to represent using a double.  Also, multiplying or dividing a double by a small constant factor (1,000,000,000 is small by double standards) is virtually guaranteed to avoid any loss of precision.  But as soon as such a utility gets std::chronified, it becomes a template.  This is because you cannot have sleepFor(std::chrono::seconds), since that wouldn’t allow you to represent fractions of seconds.  This brings me to my next point.

Overflow danger: std::chrono is based on integers and its math methods do not support overflow protection.  This has led to serious bugs like https://bugs.webkit.org/show_bug.cgi?id=157924.  This cancels out the “remember what unit is used” benefit cited above.  It’s true that I know what type of time I have, but as soon as I duration_cast it to another unit, I may overflow.  The type system does not help!  This is insane: std::chrono requires you to do more work when writing multi-unit code, so that you satisfy the type checker, but you still have to be just as paranoid around multi-unit scenarios.  Forgetting that you have milliseconds and using it as seconds is trivially fixable.  But if std::chrono flags such an error and you fix it with a duration_cast (as any std::chrono tutorial will tell you to do), you’ve just introduced an unchecked overflow and such unchecked overflows are known to cause bugs that manifest as pages not working correctly.

I think that doubles are better t

Re: [webkit-dev] RFC: stop using std::chrono, go back to using doubles for time

2016-05-22 Thread Brady Eidson

> On May 22, 2016, at 6:41 PM, Filip Pizlo  wrote:
> 
> Hi everyone!
> 
> I’d like us to stop using std::chrono and go back to using doubles for time.  
> First I list the things that I think we wanted to get from std::chrono - the 
> reasons why we started switching to it in the first place.  Then I list some 
> disadvantages of std::chrono that we've seen from fixing std::chrono-based 
> code.  Finally I propose some options for how to use doubles for time.
> 
> Why we switched to std::chrono
> 
> A year ago we started using std::chrono for measuring time.  std::chrono has 
> a rich typesystem for expressing many different kinds of time.  For example, 
> you can distinguish between an absolute point in time and a relative time.  
> And you can distinguish between different units, like nanoseconds, 
> milliseconds, etc.
> 
> Before this, we used doubles for time.  std::chrono’s advantages over doubles 
> are:
> 
> Easy to remember what unit is used: We sometimes used doubles for 
> milliseconds and sometimes for seconds.  std::chrono prevents you from 
> getting the two confused.
> 
> Easy to remember what kind of clock is used: We sometimes use the monotonic 
> clock and sometimes the wall clock (aka the real time clock).  Bad things 
> would happen if we passed a time measured using the monotonic clock to 
> functions that expected time measured using the wall clock, and vice-versa.  
> I know that I’ve made this mistake in the past, and it can be painful to 
> debug.
> 
> In short, std::chrono uses compile-time type checking to catch some bugs.
> 
> Disadvantages of using std::chrono
> 
> We’ve seen some problems with std::chrono, and I think that the problems 
> outweigh the advantages.  std::chrono suffers from a heavily templatized API 
> that results in template creep in our own internal APIs.  std::chrono’s 
> default of integers without overflow protection means that math involving 
> std::chrono is inherently more dangerous than math involving double.  This is 
> particularly bad when we use time to speak about timeouts.
> 
> Too many templates: std::chrono uses templates heavily.  It’s overkill for 
> measuring time.  This leads to verbosity and template creep throughout common 
> algorithms that take time as an argument.  For example if we use doubles, a 
> method for sleeping for a second might look like sleepForSeconds(double).  
> This works even if someone wants to sleep for a nanoseconds, since 0.01 
> is easy to represent using a double.  Also, multiplying or dividing a double 
> by a small constant factor (1,000,000,000 is small by double standards) is 
> virtually guaranteed to avoid any loss of precision.  But as soon as such a 
> utility gets std::chronified, it becomes a template.  This is because you 
> cannot have sleepFor(std::chrono::seconds), since that wouldn’t allow you to 
> represent fractions of seconds.  This brings me to my next point.
> 
> Overflow danger: std::chrono is based on integers and its math methods do not 
> support overflow protection.  This has led to serious bugs like 
> https://bugs.webkit.org/show_bug.cgi?id=157924 
> .  This cancels out the 
> “remember what unit is used” benefit cited above.  It’s true that I know what 
> type of time I have, but as soon as I duration_cast it to another unit, I may 
> overflow.  The type system does not help!  This is insane: std::chrono 
> requires you to do more work when writing multi-unit code, so that you 
> satisfy the type checker, but you still have to be just as paranoid around 
> multi-unit scenarios.  Forgetting that you have milliseconds and using it as 
> seconds is trivially fixable.  But if std::chrono flags such an error and you 
> fix it with a duration_cast (as any std::chrono tutorial will tell you to 
> do), you’ve just introduced an unchecked overflow and such unchecked 
> overflows are known to cause bugs that manifest as pages not working 
> correctly.
> 
> I think that doubles are better than std::chrono in multi-unit scenarios.  It 
> may be possible to have std::chrono work with doubles, but this probably 
> implies us writing our own clocks.  std::chrono’s default clocks use 
> integers, not doubles.  It also may be possible to teach std::chrono to do 
> overflow protection, but that would make me so sad since using double means 
> not having to worry about overflow at all.
> 
> The overflow issue is interesting because of its implications for how we do 
> timeouts.  The way to have a method with an optional timeout is to do one of 
> these things:
> 
> - Use 0 to mean no timeout.
> - Have one function for timeout and one for no timeout.
> - Have some form of +Inf or INT_MAX to mean no timeout.  This makes so much 
> mathematical sense.
> 
> WebKit takes the +Inf/INT_MAX approach.  I like this approach the best 
> because it makes the most mathematical sense: not giving a timeout is exactly 
> like asking for a timeout at 

[webkit-dev] RFC: stop using std::chrono, go back to using doubles for time

2016-05-22 Thread Filip Pizlo
Hi everyone!

I’d like us to stop using std::chrono and go back to using doubles for time.  
First I list the things that I think we wanted to get from std::chrono - the 
reasons why we started switching to it in the first place.  Then I list some 
disadvantages of std::chrono that we've seen from fixing std::chrono-based 
code.  Finally I propose some options for how to use doubles for time.

Why we switched to std::chrono

A year ago we started using std::chrono for measuring time.  std::chrono has a 
rich typesystem for expressing many different kinds of time.  For example, you 
can distinguish between an absolute point in time and a relative time.  And you 
can distinguish between different units, like nanoseconds, milliseconds, etc.

Before this, we used doubles for time.  std::chrono’s advantages over doubles 
are:

Easy to remember what unit is used: We sometimes used doubles for milliseconds 
and sometimes for seconds.  std::chrono prevents you from getting the two 
confused.

Easy to remember what kind of clock is used: We sometimes use the monotonic 
clock and sometimes the wall clock (aka the real time clock).  Bad things would 
happen if we passed a time measured using the monotonic clock to functions that 
expected time measured using the wall clock, and vice-versa.  I know that I’ve 
made this mistake in the past, and it can be painful to debug.

In short, std::chrono uses compile-time type checking to catch some bugs.

Disadvantages of using std::chrono

We’ve seen some problems with std::chrono, and I think that the problems 
outweigh the advantages.  std::chrono suffers from a heavily templatized API 
that results in template creep in our own internal APIs.  std::chrono’s default 
of integers without overflow protection means that math involving std::chrono 
is inherently more dangerous than math involving double.  This is particularly 
bad when we use time to speak about timeouts.

Too many templates: std::chrono uses templates heavily.  It’s overkill for 
measuring time.  This leads to verbosity and template creep throughout common 
algorithms that take time as an argument.  For example if we use doubles, a 
method for sleeping for a second might look like sleepForSeconds(double).  This 
works even if someone wants to sleep for a nanoseconds, since 0.01 is easy 
to represent using a double.  Also, multiplying or dividing a double by a small 
constant factor (1,000,000,000 is small by double standards) is virtually 
guaranteed to avoid any loss of precision.  But as soon as such a utility gets 
std::chronified, it becomes a template.  This is because you cannot have 
sleepFor(std::chrono::seconds), since that wouldn’t allow you to represent 
fractions of seconds.  This brings me to my next point.

Overflow danger: std::chrono is based on integers and its math methods do not 
support overflow protection.  This has led to serious bugs like 
https://bugs.webkit.org/show_bug.cgi?id=157924 
.  This cancels out the 
“remember what unit is used” benefit cited above.  It’s true that I know what 
type of time I have, but as soon as I duration_cast it to another unit, I may 
overflow.  The type system does not help!  This is insane: std::chrono requires 
you to do more work when writing multi-unit code, so that you satisfy the type 
checker, but you still have to be just as paranoid around multi-unit scenarios. 
 Forgetting that you have milliseconds and using it as seconds is trivially 
fixable.  But if std::chrono flags such an error and you fix it with a 
duration_cast (as any std::chrono tutorial will tell you to do), you’ve just 
introduced an unchecked overflow and such unchecked overflows are known to 
cause bugs that manifest as pages not working correctly.

I think that doubles are better than std::chrono in multi-unit scenarios.  It 
may be possible to have std::chrono work with doubles, but this probably 
implies us writing our own clocks.  std::chrono’s default clocks use integers, 
not doubles.  It also may be possible to teach std::chrono to do overflow 
protection, but that would make me so sad since using double means not having 
to worry about overflow at all.

The overflow issue is interesting because of its implications for how we do 
timeouts.  The way to have a method with an optional timeout is to do one of 
these things:

- Use 0 to mean no timeout.
- Have one function for timeout and one for no timeout.
- Have some form of +Inf or INT_MAX to mean no timeout.  This makes so much 
mathematical sense.

WebKit takes the +Inf/INT_MAX approach.  I like this approach the best because 
it makes the most mathematical sense: not giving a timeout is exactly like 
asking for a timeout at time-like infinity.  When used with doubles, this Just 
Works.  +Inf is greater than any value and it gets preserved properly in math 
(+Inf * real = +Inf, so it survives gracefully in unit conversions; +Inf + real 
= +Inf, so it also survives