+1 for duck typing, a custom non-Date object can look like a date for operations that only use a subset of the methods.
If you know your format (iso8601, etc), you're better off just using the right parser instead of Date.parse.
Also the internal representation uses Rational, which can be pretty slow itself.
Date.parse: http://github.com/ruby/ruby/blob/trunk/lib/date/format.rb#L1...
edit: correction to how parse works.
I don't know why their version is so slow, I can only imagine that the conversion to Astronomical Julian Day (the Ruby Date internal representation) is expensive, inefficient or both.
I used year/month/day ints as internal representation, which was fast for my use cases (parse date string, format date string, compare two dates).