Monthly Archive for March, 2008

Hash tables and hash codes

In my previous post, I mentioned that I'm considering using a hash table to speed up retrieval of an already-created evaluator.  The general idea is that I would construct a hash table key consisting of three pieces of information:

  1. The definitional object that created the evaluator.
  2. The method on the definitional object that created the evaluator.
  3. Any parameters passed to the method above.  In many cases, the parameters will themselves be definitional objects.

The hash table would then map this key to an actual evaluator instance.  If someone requests that I create another evaluator with the same key as a previous one, I can just return that previous evaluator instead of constructing another one.

It sounds straightforward enough, but a couple of things conspire to make it tricky. Read on.

Continue reading 'Hash tables and hash codes'

Improving Evaluators and EvaluatorGroups

I'm working on some changes to evaluators and EvaluatorGroups in DGL. My two main goals are to reduce the time it takes to construct an evaluator instance and (more importantly) make it easier to write new evaluators. Read on to learn about some of the things I'm considering doing.

Continue reading 'Improving Evaluators and EvaluatorGroups'

DateTime likes to throw away your precision

Now that the introductions are out of the way, it's time to start the ranting!

A customer reported today that our JulianDate.ToDateTime method was returning a DateTime rounded to the nearest millisecond. A little digging revealed him to be absolutely correct. This was surprising because a .NET DateTime stores "ticks" which are 100-nanosecond intervals, considerably more precise than a millisecond.

A little more digging traced the problem to the DateTime.AddSeconds method. Our code calls this method as part of the implementation of ToDateTime.

The MSDN documentation for DateTime.AddSeconds has this to say on the subject:

The value parameter is rounded to the nearest millisecond.

Well I'll be a monkey's uncle. Or something. That's certainly not what we expected. Or wanted.

So an hour later I had a new implementation of JulianDate.ToDateTime passing my test case for this bug. The new implementation uses AddTicks, which thankfully does not do any rounding, instead of the problematic AddSeconds.

There's a lesson here. DateTime is great as long as:

  • You don't need to represent times more precisely than 100-nanoseconds.
  • If you need to represent times more precisely than 1-millisecond, you carefully read the documentation to make sure that DateTime is not doing any covert rounding.
  • You don't need to take leap seconds into account at all.

Of course, these limitations probably mean that DateTime is poorly suited for most aerospace and astrodynamics applications.  We highly recommend that you use our JulianDate type instead wherever possible.

At some point in the not-too-distant future, we will introduce a GregorianDate type to Dynamic Geometry Library which will combine many of the strengths of DateTime and JulianDate and eliminate the glaring weaknesses cited above.