On 8/4/03 12:26 AM, Dave Rolsky wrote: >> # "..." includes args: year, month, day, hour, minute, second >> DateTime->new(...): 16 wallclock secs @ 687.29/s >> (14.48 usr + 0.07 sys = 14.55 CPU) > > This does a lot of work, including calculating both UTC & local times, > which involves calculating leap seconds, etc.
Does it need to do that? I mean, sure, eventually it might have to do that if I want to do some sort of date manipulation, or even just fetch or print the date. But does it have to really do anything at all during object construction other than stash the args somewhere? >> DateTime->now(): 21 wallclock secs @ 547.95/s >> (18.13 usr + 0.12 sys = 18.25 CPU) > > Ditto. I'm assuming now() is slower than new() due to the system call overhead of getting the current time...? >> Total Elapsed Time = 19.91729 Seconds >> User+System Time = 14.60729 Seconds >> Exclusive Times >> %Time ExclSec CumulS #Calls sec/call Csec/c Name >> 27.6 4.035 4.685 20274 0.0002 0.0002 Params::Validate::_validate >> 24.0 3.510 17.549 10000 0.0004 0.0018 DateTime::new >> 18.9 2.770 3.809 10001 0.0003 0.0004 >> DateTime::Locale::_load_class_from_id > > This seems quite odd. It really doesn't do much. > >> 8.96 1.309 2.647 10020 0.0001 0.0003 DateTime::TimeZone::BEGIN > > And this is completely mystifying. Can you show us your code? Sure, here it is: for(1 .. 10000) { my $d = DateTime->new(year => 200, month => 1, day => 1, hour => 2, minute => 3, second => 4); } Those stats were produced on a G3/400 running a development release of OS X that uses some build of Perl 5.8.1, which could explain some oddness. Here is the same code run on a G4/800 using Perl 5.8.0 on the latest released version of OS X 10.2: Total Elapsed Time = 8.817281 Seconds User+System Time = 5.352659 Seconds Exclusive Times %Time ExclSec CumulS #Calls sec/call Csec/c Name 60.4 3.236 10.844 10000 0.0003 0.0011 DateTime::new 44.7 2.395 3.305 10001 0.0002 0.0003 DateTime::Locale::_load_class_from_id 43.3 2.318 2.127 20274 0.0001 0.0001 Params::Validate::_validate 22.5 1.207 1.095 10001 0.0001 0.0001 DateTime::Locale::Base::new 18.4 0.987 1.223 10020 0.0001 0.0001 DateTime::TimeZone::BEGIN 17.5 0.939 0.465 50000 0.0000 0.0000 DateTime::__ANON__ 15.2 0.818 0.645 10002 0.0001 0.0001 DateTime::_calc_local_components 12.8 0.687 1.025 10002 0.0001 0.0001 DateTime::_calc_local_rd 10.6 0.568 0.525 10002 0.0001 0.0001 DateTime::_calc_utc_rd 8.20 0.439 0.225 10002 0.0000 0.0000 DateTime::_normalize_seconds 7.83 0.419 0.275 10000 0.0000 0.0000 DateTime::_last_day_of_month 7.47 0.400 0.115 30006 0.0000 0.0000 DateTime::TimeZone::Floating::is_floating 7.27 0.389 3.505 10001 0.0000 0.0004 DateTime::Locale::load 5.79 0.310 0.214 10006 0.0000 0.0000 DateTime::TimeZone::Floating::BEGIN 4.86 0.260 0.070 20004 0.0000 0.0000 DateTime::TimeZone::OffsetOnly::is_utc Maybe that looks more sane to you? >> So, what does everyone else think of the object creation performance >> situation? Is it simply "good enough" to be "3x faster that >> Date::Manip::ParseDate()"? Are there any obvious areas that I should >> consider before I start mucking around with DateTime::new()? > > Considering that up til now my concern has been primarily on getting > things correct, I wouldn't worry about it. There are definitely some big > performance improvements possible. One possibility is to move the leap > second bits into the DateTime XS code, which should help a lot. The > timezone stuff can also benefit from being rewritten as XS, but that won't > help the particular cases you benchmarked, since the UTC and floating time > zones are quite fast already. What about what I mentioned earlier: lazy (or "lazier") evaluation in the constructor? Basically, I want construction with known values to be as fast as possible since there's a chance I may not even look at the date fields of my objects. But it's a hassle to have special-case code that either doesn't fetch or doesn't set the date fields of my objects, just so I can avoid the relatively expansive calls to DateTime->new() -John