I've discovered a few problems with time.Time but thought I better discuss 
here first before creating issues at https://github.com/golang/go/issues 
(in case I missed something obvious :).  These are mainly performance 
issues, but there is also the serious problem that it is easy to 
accidentally disable "monotonic" time differences (reverting to "wall" 
time) and that you cannot obtain a monotonic time with *Location == nil 
(UTC).

This all began with real software that generates (using time.Now()) and 
retains millions of timestamps (in memory) used for various purposes 
including the deletions of old data by comparing these times with "now". 
 Due to the large number of calls to time.Now() performance is important, 
accounting for a significant proportion of processing time.

The first optimization made (some time ago) was to replace calls to 
time.Now() with time.Now.UTC() in an attempt to reduce the load on the 
garbage collector.  (Calling the UTC() method sets the *Location field to 
nil which obviates the GC need to follow the pointer I believe.)

Recent benchmarking revealed that calling calling time.Now().UTC() takes 
more than twice as long as calling time.Now().  Moreover, time.Now() has 
some code that is effectively "dead" (never executed) which could reduce 
that it by another 30% -- there is an if statement that will always return 
false until after the current time is well into the future (after 2150 or 
so).

A further issue I found from inspecting the code for the UTC() method is 
that calling it clears the hasMonotonic flag and subsequent time 
comparisons use "wall" time - this affects many calls to 
ContextWithDeadline().  The only discussion I can find on why calling UTC() 
should clear the hasMonotonic flag is this comment from Russ Cox 
[https://github.com/golang/go/issues/18991#issuecomment-306209288] which 
does not explain what tests are fixed or even what is being tested.

I find it particularly worrisome that you can easily and inadvertently turn 
off "monotonic" time comparisons.

Some changes I might propose are:
1. Removal of the dead code in time.Now()
2. Calling UTC() should not clear the hasMonotonic flag
3. Passing a non-monotonic time to contextWithDeadline should panic
4. Add a new function (eg, time.NowUTC()) to efficiently get the current 
monotonic, UTC time 

These changes (except for 4) have backward compatibility implications which 
I have considered (and believe will be acceptable) but will need further 
research and discussion.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/8f20d976-49f8-499f-a4f9-3f8fd8320b13n%40googlegroups.com.

Reply via email to