[squeak-dev] Some DateAndTime experiments
David T. Lewis
lewis at mail.msen.com
Sat Apr 19 13:12:47 UTC 2014
On Sat, Apr 19, 2014 at 10:34:04AM +0200, Nicolas Cellier wrote:
> Hi Dave,
> did you lurk at the work in Pharo?
> I think they followed similar approach, but they kept jdn seconds and
> nanos, representing time in UTC, and they used UTC clock exlcusively.
> It would be interesting to compare the timings vs latest Pharo (3.0).
Yes, I'm aware of the Pharo work.
The approach that I am trying now is based on my earlier work with the
Olson time zone tables in http://www.squeaksource.com/TimeZoneDatabase.
In order to make that work with DateAndTime, I use a class called
PointInTime that is a magnitude representing UTC time in seconds. This
makes the time zone table lookups simple, and it makes the conversions
to and from DateAndTime easier to test and to understand.
I always thought that it would be interesting to "eliminate the middle
man" in this scheme by making DateAndTime be clearly based on a UTC time
scale. So that is what I am trying now.
> A single variable is interesting for simplifying implementation.
> I wonder about the required precision though...
> There are about 2^20 microseconds in a second, and about 2^31 seconds in
> about 68 years.
> So with a Double, you can span about 4*68 years, in the future of epoch
> (same in the past), while keeping the microsecond precision.
> That seems well enough, considering that second precision for an event
> several centuries ago is sufficient.
> And with the avent of SmallDouble in 64 bits Spur, that would be certainly
> more efficient than now.
Interesting that you should say that. In the PointInTime class, I originally
used Float (double) to represent UTC seconds for exactly the reason you
say. It works well, but I tried some other representations and found that
ScaledDecimal provided the best results overall, with good performance and
very nice charactistics for displaying the UTC seconds in an inspector.
But overall, the best approach seems to be just let it be a Number and
don't worry about it. In actual practice, if the UTC time is represented
in units of microsecond, this results in integer values in all practical
cases. In the rare case of specifying nanosecond precision, you get fractions,
which are reasonably efficient also.
> But nanos would cost 10 more bits and be rapidly out of reach (with a span
> of +/- 3 month around the epoch)...
> I'm afraid that using a Fraction (ScaledDecimal) be an efficiency killer,
> but I didn't measure anything...
ScaledDecimal turns out be be surprisingly good in performance. Despite
its instance variable names ("fraction"), it actually uses integers when
fractions are not required, so it is quite efficient. If I wanted to
explicitly control the type of number used to represent UTC time, I would
> 2014-04-19 4:42 GMT+02:00 David T. Lewis <lewis at mail.msen.com>:
> > I have been experimenting with a new implementation of DateAndTime based
> > on a UTC magnitude. In this implementation, the instance variables jdn,
> > seconds, and nanos are replaced with a single utcMicroseconds, and the
> > offset (a Duration) is replaced by localOffsetSeconds (an integer). The
> > UTC magnitude and offset are provided directly by primitiveUtcWithOffset
> > when doing DateAndTime now.
> > I had hoped to achieve a sigificant performance advantage with this
> > implementation, and while it does improve performance, I am only seeing
> > about a 10% improvement overall, which is considerably less than I had
> > hoped.
> > Nevertheless, it is indeed faster, and implemention does have some
> > interesting
> > characteristics.
> > The utcMicroseconds magnitude is in units of microseconds, but it is not
> > required to be an integer and may represent time to any precision. In
> > practice,
> > values are integral unless the instance is explicitly created with a
> > nanosecond
> > value.
> > New instances created by "DateAndTime now" will have the correct time zone
> > offset as provided by the operating system platform, and their magnitude is
> > set to a UTC value the precision provided by the platform.
> > New instances created by other constructors use TimeZone default, which is
> > problematic given that the time zone in Squeak may or may not match the
> > (presumably correct) values provided by the operating system.
> > Instances of DateAndTime are (at the moment) considered equal if their
> > magnitudes
> > are the same, independent of the time zone offset. This makes sense when
> > thinking
> > of them as magnitudes (DateAndTime is a Magnitude), but saying that two
> > instances
> > with different local offsets are equal might be wrong in other contexts.
> > The localOffsetSeconds is used for displaying the date and time, and is not
> > related to magnitude. Thus a DateAndTime is both a magnitude (UTC time)
> > and a
> > formatter (use the offset to show the magnitude in the context of a local
> > time zone).
> > Dave
More information about the Squeak-dev