From: Jeremy Evans Date: 2010-09-10T02:40:58+09:00 Subject: [ruby-core:32248] Replacing stdlib Date with C version I've recently been working on a replacement for the stdlib Date class, called home_run. It's written in C and is much faster than the stdlib version. On 1.9.2, it's about 2-70x faster than the stdlib for common operations. See http://github.com/jeremyevans/home_run With speed comes a price, which is that it is not fully compatible, and it would be difficult to make it fully compatible without greatly increasing the complexity of the library. Here are the differences I know about between the stdlib and home_run: * Written in C (mostly) instead of ruby. Stores information in a C structure, and therefore has a range limitation. home_run cannot handle dates after 5874773-08-15 or before -5877752-05-08 on 32-bit platforms (with larger limits for 64-bit platforms). * The Date class does not store fractional days (e.g. hours, minutes), or offsets. The DateTime class does handle fractional days and offsets. * The DateTime class stores fractional days as the number of nanoseconds since midnight, so it cannot deal with differences less than a nanosecond. * Neither Date nor DateTime uses rational. Places where the standard library returns rationals, home_run returns integers or floats. * Because rational is not used, it is not required. This can break other libraries that use rational without directly requiring it. * There is no support for modifying the date of calendar reform, the sg arguments are ignored and the Gregorian calendar is always used. This means that julian day 0 is -4173-11-24, instead of -4712-01-01. * The undocumented Date#strftime format modifiers are not supported. * The DateTime offset is checked for reasonableness. home_run does not support offsets with an absolute difference of more than 14 hours from UTC. * DateTime offsets are stored in minutes, so it will round offsets with fractional minutes to the nearest minute. * All public class and instance methods for both Date and DateTime are implemented, except that the allocate class method is not available and on 1.9, _dump and _load are used instead of marshal_dump and marshal_load. * Only the public API is compatible, the private methods in the standard library are not implemented. * The marshalling format differs from the one used by the standard library. Note that the 1.8 and 1.9 standard library date marshalling formats differ from each other. * Date#step treats the step value as an integer, so it cannot handle steps of fractional days. DateTime#step can handle fractional day steps, though. * When parsing the %Q modifier in _strptime, the hash returned includes an Integer :seconds value and a Float :sec_fraction value instead of a single rational :seconds value. * The string returned by #inspect has a different format, since it doesn't use rational. * You can use the Date::Format::STYLE hash to change how to parse DD/DD/DD and DD.DD.DD date formats, allowing you to get ruby 1.9 behavior on 1.8 or vice-versa. This is probably the only new feature in that isn't in the standard library. It's possible to make home_run more compatible with the stdlib, for example by supporting the date of calendar reform or by supporting the undocumented strftime modifiers. Changes such as supporting rational or fractional nanoseconds would be significantly more involved. I designed home_run so that it would fully serve the needs of 99% of rubyists. For the 1% that need the features that home_run does not provide, they could either use the current stdlib (either moved elsewhere in the stdlib or made available as a gem), or Tadayoshi Funaba's date2 or date4 libraries (http://www.funaba.org/en/ruby.html). There are a couple possible issues with home_run's implementation that do not affect backwards compatibility but you may want to consider: * home_run stores fractional days (nanoseconds since midnight) in a long long. So the current version would not work on platforms that don't support long long. * home_run uses Ragel to speed up Date._parse for common date formats. This means that you need Ragel if you want to modify the C parser. The Ragel/C parser is only used to speed up parsing, if it doesn't match, home_run falls back on using a faster version of the current date/format.rb. So my questions for ruby-core: * Is it possible to replace the current stdlib date support with home_run? * If so, could it be taken as is, or are changes to increase backwards compatibility required first? * If changes are required first, which changes would you like to see? * If you don't think it is a good idea to replace the current stdlib with home_run, could you give a short explanation of your reasoning? Thank you, Jeremy Evans