Chronos is one of the many Smalltalk-related blogs syndicated on Planet Smalltalk
χρόνος

Discussion of the Essence# programming language, and related issues and technologies.

Blog Timezone: America/Los_Angeles [Winter: -0800 hhmm | Summer: -0700 hhmm] 
Your local time:  

2006-04-12

The Timing of Time: Chronos Benchmarks

The time has come, the benchmarker said, to speak of many things. Of dates and times and cold, hard facts, of durations and timings. Of why the code is boiling hot and whether Chronos has wings (with apologies to Lewis Carrol.)

To put it less poetically: What follows are some benchmars comparing the Squeak version of Chronos (Version B1.167) with Squeak's native Chronology library.

First, let's level set. I've been working on Chronos since October 2004, and although it's my first attempt to implement a date/time library in Smalltalk, and it's the first time I've ever implemented a date/time library as a hobby without being paid by an employer, it's not at all the first date/time library I've implemented. I essentially "started from scratch" on the fundamental architecture/design of Chronos at least three or four times. I have spared no expense in time, effort or amount of code to achieve both the functionality I was determined that Chronos should have, and also the level of performance I thought was necessary/achievable. In other words, you should have every right to expect that Chronos would generally exceed the level of performance provided by the "out of the box" date/time libraries as distributed with the various Smalltalk implementations.

Also, it should be noted that Squeak is among the august group of Smalltalk implementations that make any attempt to have their date/time package conform to the ANSI Smalltalk Standard (VisualAge, Gnu Smalltalk and #Smalltalk are the only others, as far as I am aware.) More than that, Squeak's Chronology package exceeds the ANSI-required functionality, in that it offers significant and useful behavior related to intervals of time.

1. The hardware and software used for the benchmarks:

CPU: AMD FX-55
Chipset: nForce4-Ultra
Motherboard: MSI K8n Neo4
RAM: 2GB DDR400
OS: Windows XP, SP2
Squeak Version: 3.8.
Chronos version: B1.167

2. System Clock (Primitive 137)

The system clock benchmark measures the amount of time required to perform 1,000,000 invocations of Squeak primitive 137. Both Chronos and Chronology rely on this primitive in order to answer the current date and/or time-of-day, and so it's useful to measure the amount of time required to execute this primitive, since it is used by both Chronos and Chronology:

[1000000 timesRepeat: [SystemClock ticksNowSinceSystemClockEpoch]] durationToRun => 0:00:00:00.462 (0.462 seconds)

3. Get current date/time--without any subsequent queries

Chronology:
[1000000 timesRepeat: [DateAndTime now]] durationToRun => 0:00:00:44.556 (44.556 seconds)

Chronos:
[1000000 timesRepeat: [Timepoint now]] durationToRun => 0:00:00:06.241 (6.241 seconds)

4. Get current date/time, then query result for year, month, dayOfMonth

Chronology:
[1000000 timesRepeat: [DateAndTime now year; month; dayOfMonth]] durationToRun => 0:00:00:49.364

Chronos:
[1000000 timesRepeat: [Timepoint now year; month; dayOfMonth]] durationToRun => 0:00:00:09.605

5. Get current date/time, then query result for dayOfYear

Chronology:
[1000000 timesRepeat: [DateAndTime now dayOfYear]] durationToRun => 0:00:02:34.078 (154 seconds)

Chronos:
[1000000 timesRepeat: [Timepoint now dayOfYear]] durationToRun => 0:00:00:08.982 (less than 9 seconds)

6. Get today's date

Chronology:
[1000000 timesRepeat: [Date today]] durationToRun => 0:00:01:45.931

Chronos:
[1000000 timesRepeat: [YearMonthDay today]] durationToRun => 0:00:00:09.897

7. Get current time-of-day

Chronology:
[1000000 timesRepeat: [Time now]] durationToRun => 0:00:00:22.68

Chronos:
[1000000 timesRepeat: [TimeOfDay now]] durationToRun => 0:00:00:09.525

8. Create point-in-time value from YYYY-MM-DDTHH:MM:SS parameters

Chronology:
[1000000 timesRepeat: [(DateAndTime year: 2006 month: 7 day: 23 hour: 4 minute: 55 second: 16)]] durationToRun => 0:00:00:45.891

Chronos:
[1000000 timesRepeat: [(Timepoint year: 2006 month: 7 day: 23 hour: 4 minute: 55 second: 16)]] durationToRun => 0:00:00:04.004

9. Create point-in-time value from count of seconds

Chronology:
[1000000 timesRepeat: [(DateAndTime fromSeconds: 3331083316)]] durationToRun => 0:00:00:43.938

Chronos:
[1000000 timesRepeat: [(Timepoint secondsSinceEpoch: 63289227316)]] durationToRun => 0:00:00:03.486

Note: In the above, although the count of seconds differs, both expressions evaluate to the same date/time value--and the Chronos example has one more digit.

10. Add 50 days to a date

Chronology:
| tp |
tp := Date today.
[1000000 timesRepeat: [tp addDays: 50]] durationToRun => 0:00:01:24.046

Chronos:
| tp |
tp := YearMonthDay today.
[1000000 timesRepeat: [tp addingDays: 50]] durationToRun => 0:00:00:01.733

11. Add 500 days to a point-in-time

Chronology:
| tp duration |
tp := DateAndTime now.
duration := Duration days: 500.
[1000000 timesRepeat: [tp + duration]] durationToRun => 0:00:00:11.112

Chronos:
| tp |
tp := Timepoint now.
[1000000 timesRepeat: [tp addingDays: 500]] durationToRun => 0:00:00:01.217

And that should be enough to see the general trend, as far as the performance of Chronos relative to Squeak's Chronology package is concerned.


No comments: