[squeak-dev] The Inbox: Chronology-Core-eem.22.mcz

Eliot Miranda eliot.miranda at gmail.com
Fri Jan 11 19:29:53 UTC 2019


Hi David,

> On Jan 11, 2019, at 11:15 AM, David T. Lewis <lewis at mail.msen.com> wrote:
> 
>> On Fri, Jan 11, 2019 at 09:43:03AM -0800, Eliot Miranda wrote:
>> 
>> 
>>> On Jan 10, 2019, at 6:20 PM, David T. Lewis <lewis at mail.msen.com> wrote:
>>> 
>>> This is a good optimization. After taking a brief look at the performance
>>> numbers, I can see a significant (almost 2X) improvement in DateAndTime>>asTime.
>> 
>> In 32-bit or 64-bit?
> 
> This is on 64-bit, I did not check 32-bit.

Can you post the test?  I’d like to measure 32-bits where the difference should be larger.

> 
> Dave
> 
>> 
>>> But I cannot really find any other examples where there is a measurable
>>> improvement. I'm not sure that it's a big performance win in real world
>>> use cases.
>>> 
>>> I recently spent a good deal of time with Chris Muller looking at performance
>>> implications of the UTC updates for DateAndTime, and I learned that changes
>>> to the shape of DateAndTime (specifically the instVar count) can have some
>>> unanticipated side effects for IO to external systems (serialization,
>>> databases, Magma).
>>> 
>>> My perspective is that this is a good optimization, but we might want
>>> to hold off on putting it into trunk for a while, at least until folks
>>> have had a chance to get comfortable with the new two instVar format
>>> of DateAndTime.
>> 
>> I???m good with that :-)
>> 
>>> 
>>> Dave
>>> 
>>> 
>>>> On Thu, Jan 10, 2019 at 08:50:30AM -0500, David T. Lewis wrote:
>>>> I am away and cannot look at this now, but on the face of it, it sounds
>>>> like a good optimization, so if it makes a meaningful difference to
>>>> performance then we should consider it.
>>>> 
>>>> One clarification to Chris' comment - we (or at least I) did not expect
>>>> UTCDateAndTime to be slower on 32-bit images. In fact, when I measured
>>>> it (quite a long time ago now) it was faster on 32-bit images, and faster
>>>> yet on 64-bit images. But my benchmarks were trivial, and Chris is
>>>> considering use cases that involve IO to disk, and those might have
>>>> very different performance considerations.
>>>> 
>>>> The simple performance checks that I was using can be found in
>>>> package Tests-UTCDateAndTime in the www.squeaksource.com/UTCDateAndTime
>>>> repository. I can't look at it now, but those tests might be a useful
>>>> reference here.
>>>> 
>>>> Dave
>>>> 
>>>>> On Wed, Jan 09, 2019 at 10:38:04PM -0600, Chris Muller wrote:
>>>>> -1.  DateAndTime is an object of which there are often many instances.
>>>>> Adding another inst var increases size and processing to spin through
>>>>> yet one more variable during disk-read, transmission and serialization
>>>>> and materialization.  It's pure cost for 64-bit images, since there
>>>>> isn't any LI arithmetic there anyway, and *we knew* going in that
>>>>> UTCDateAndTime would be slower in 32-bit.  Avoiding LI arithmetic in
>>>>> 32-bit is what the original Chronology did....
>>>>> 
>>>>> Regards,
>>>>> Chris
>>>>> 
>>>>> 
>>>>> 
>>>>>> On Wed, Jan 9, 2019 at 8:53 PM <commits at source.squeak.org> wrote:
>>>>>> 
>>>>>> A new version of Chronology-Core was added to project The Inbox:
>>>>>> http://source.squeak.org/inbox/Chronology-Core-eem.22.mcz
>>>>>> 
>>>>>> ==================== Summary ====================
>>>>>> 
>>>>>> Name: Chronology-Core-eem.22
>>>>>> Author: eem
>>>>>> Time: 9 January 2019, 6:53:52.265064 pm
>>>>>> UUID: 348c4ad7-0a27-4021-8788-9e3ec220df24
>>>>>> Ancestors: Chronology-Core-ul.21
>>>>>> 
>>>>>> Simple speedup by caching the result of getSeconds in an inst var.  Lots of other values are defined in terms of getSeconds so this simply eliminates duplicating the large integer arithmetic in getSeconds.
>>>>>> 
>>>>>> =============== Diff against Chronology-Core-ul.21 ===============
>>>>>> 
>>>>>> Item was changed:
>>>>>> Magnitude subclass: #DateAndTime
>>>>>> +       instanceVariableNames: 'utcMicroseconds localOffsetSeconds seconds'
>>>>>> -       instanceVariableNames: 'utcMicroseconds localOffsetSeconds'
>>>>>>       classVariableNames: 'AutomaticTimezone ClockProvider InitializeFromPrimitive LocalTimeZone PosixEpochJulianDays'
>>>>>>       poolDictionaries: 'ChronologyConstants'
>>>>>>       category: 'Chronology-Core'!
>>>>>> 
>>>>>> + !DateAndTime commentStamp: 'eem 1/9/2019 18:44' prior: 0!
>>>>>> - !DateAndTime commentStamp: 'dtl 3/12/2016 10:32' prior: 0!
>>>>>> I represent a point in UTC time as defined by ISO 8601. I have zero duration.
>>>>>> 
>>>>>> + My implementation uses variables utcMicroseconds and localOffsetSeconds. This represents time magnitude as elapsed microseconds since the Posix epoch, with localOffsetSeconds representing local offset from UTC. The magnitude is used for comparison and duration calculations, and the local offset is used for displaying this magnitude in the context of a local time zone.  I cache the result of getSeconds in the seconds variable that is computed when required.
>>>>>> - My implementation uses variables utcMicroseconds and localOffsetSeconds. This represents time magnitude as elapsed microseconds since the Posix epoch, with localOffsetSeconds representing local offset from UTC. The magnitude is used for comparison and duration calculations, and the local offset is used for displaying this magnitude in the context of a local time zone.
>>>>>> 
>>>>>> The implementation ignores leap seconds, which are adjustments made to maintain earth rotational clock time in synchronization with elapsed seconds.
>>>>>> 
>>>>>> DateAndTime class>>now will use #primitiveUtcWithOffset to obtain current time in UTC microseconds with current local offset in seconds. The primitive provides an atomic query for UTC time and local offset as measured by the OS platform.  If primitiveUtcWithOffset is not available, the traditional implementation is used, which relies on a primitive for microseconds in the local time zone and derives UTC based on the TimeZone setting.
>>>>>> !
>>>>>> 
>>>>>> Item was changed:
>>>>>> ----- Method: DateAndTime>>getSeconds (in category 'accessing') -----
>>>>>> getSeconds
>>>>>> -
>>>>>>       | posixDays posixSeconds localSeconds |
>>>>>> +       seconds ifNil:
>>>>>> +               [posixSeconds := utcMicroseconds // 1000000.
>>>>>> +                localSeconds := posixSeconds + localOffsetSeconds.
>>>>>> +                localSeconds < 0 ifTrue: [localSeconds := localSeconds \\ SecondsInDay]. "normalize"
>>>>>> +                posixDays := localSeconds // SecondsInDay.
>>>>>> +                seconds := localSeconds - (posixDays * SecondsInDay)].
>>>>>> +       ^seconds!
>>>>>> -       posixSeconds := utcMicroseconds // 1000000.
>>>>>> -       localSeconds := posixSeconds + localOffsetSeconds.
>>>>>> -       localSeconds < 0 ifTrue: [localSeconds := localSeconds \\ SecondsInDay]. "normalize"
>>>>>> -       posixDays := localSeconds // SecondsInDay.
>>>>>> -       ^localSeconds - (posixDays * SecondsInDay).
>>>>>> - !
>>>>>> 
>>>>>> Item was changed:
>>>>>> ----- Method: DateAndTime>>readDataFrom:size: (in category 'objects from disk') -----
>>>>>> readDataFrom: aDataStream size: varsOnDisk
>>>>>>       "Fill in the fields of self based on the contents of aDataStream. The serialized
>>>>>>       data will have four instance variables, because all instances are serialized in a
>>>>>>       cononical format as if having originating from an instance with the traditional
>>>>>>       seconds/offset/jdn/nanos instance variables."
>>>>>> 
>>>>>>       | seconds offset jdn nanos |
>>>>>>       seconds := aDataStream next.
>>>>>>       offset := aDataStream next.
>>>>>>       jdn := aDataStream next.
>>>>>>       nanos := aDataStream next.
>>>>>>       localOffsetSeconds := offset ifNil: [ 0 ] ifNotNil: [ :off | off asSeconds ].
>>>>>>       utcMicroseconds := self
>>>>>>                               microsecondsFromDay: jdn
>>>>>>                               seconds: seconds
>>>>>>                               nanos: nanos
>>>>>> +                               offset: localOffsetSeconds..
>>>>>> +       seconds := nil!
>>>>>> -                               offset: localOffsetSeconds.!
>>>>>> 
>>>>>> Item was changed:
>>>>>> ----- Method: DateAndTime>>setJdn:seconds:nano:localOffsetSeconds: (in category 'private') -----
>>>>>> setJdn: jdn seconds: s nano: n localOffsetSeconds: offset
>>>>>> 
>>>>>>       localOffsetSeconds := offset.
>>>>>>       utcMicroseconds := self
>>>>>>                               microsecondsFromDay: jdn
>>>>>>                               seconds: s
>>>>>>                               nanos: n
>>>>>> +                               offset: offset.
>>>>>> +       seconds := nil!
>>>>>> -                               offset: offset!
>>>>>> 
>>>>>> Item was changed:
>>>>>> ----- Method: DateAndTime>>ticks:offset: (in category 'private') -----
>>>>>> ticks: ticks offset: utcOffset
>>>>>>       "ticks is {julianDayNumber. secondCount. nanoSeconds}"
>>>>>> 
>>>>>>       | jdn s nanos |
>>>>>>       self normalize: 3 ticks: ticks base: NanosInSecond.
>>>>>>       self normalize: 2 ticks: ticks base: SecondsInDay.
>>>>>> 
>>>>>>       jdn     := ticks at: 1.
>>>>>>       s := ticks at: 2.
>>>>>>       nanos := ticks at: 3.
>>>>>>       localOffsetSeconds := utcOffset ifNil: [0] ifNotNil: [utcOffset asSeconds].
>>>>>>       utcMicroseconds := self microsecondsFromDay: jdn seconds: s nanos: nanos offset: localOffsetSeconds.
>>>>>> +       seconds := nil!
>>>>>> - !
>>>>>> 
>>>>>> Item was changed:
>>>>>> ----- Method: DateAndTime>>utcMicroseconds: (in category 'initialize-release') -----
>>>>>> utcMicroseconds: utcValue
>>>>>>       "Allow value to be modified during initialization from a primitive in order to support
>>>>>>       monotonically increasing clock behavior."
>>>>>> +       utcMicroseconds := utcValue.
>>>>>> +       seconds := nil!
>>>>>> -       utcMicroseconds := utcValue!
>>>>>> 
>>>>>> Item was changed:
>>>>>> ----- Method: DateAndTime>>utcMicroseconds:offset: (in category 'initialize-release') -----
>>>>>> utcMicroseconds: microsecondsSincePosixEpoch offset: tzOffset
>>>>>> 
>>>>>>       utcMicroseconds := microsecondsSincePosixEpoch.
>>>>>>       localOffsetSeconds := tzOffset.
>>>>>> +       seconds := nil
>>>>>> !
>>>>>> 
>>>>>> 
>>>>> 
>>>> 
>>> 
>> 
> 


More information about the Squeak-dev mailing list