RE: DateTime performance
From: Philipp K. Janert [mailto:jan...@ieee.org] Sent: Wednesday, 2 May 2012 8:29 AM Question: When using DateTime for a large number of instances, it becomes a serious performance drag. ... Is this expected behavior? And are there access patterns that I can use to mitigate this effect? (I tried to supply a time_zone explicitly, but that does not seem to improve things significantly.) Hi Phillip, My #1 tip is to pre-prepare/cache the DateTime::TimeZone object and pass it in to each creation of a DateTime object (via whatever mechanism you're using to do that). I have seen a case where we were using time_zone = 'local' in a reasonably tight datetime object creation loop and saw significant speed increases just by cutting out that chunk of processing. In hindsight that was a silly thing to do but it became an easy win :-) I apologise if this is what you meant by supplying a time_zone explicitly in your comment above. I can't recommend using a tool like NYTProf highly enough on a run of your tool to spot the low hanging fruit. See https://metacpan.org/module/Devel::NYTProf Cheers, Andrew
RE: Question regarding DateTime::Format::Duration
Hi Zefram, From: Zefram [mailto:zef...@fysh.org] Andrew O'Brien wrote: Can anyone explain why parse_duration() gives me 11 days, 8044 minutes plus change? (that's around 5.5 extra days) ? 8044 minutes is 134 hours plus 4 minutes. You also got 5 seconds instead of the expected 45. So altogether you got 11:0134:4:5 rather than the expected 11:01:34:45. The digits are being misallocated. This happens because you didn't say how many digits the hours, minutes, and seconds should have, so they're allowed one or more by default, and the first of them (hours) greedily takes as many digits as it can get away with. The parsing is done by a regexp underneath, and the regexp is something like /(\d{8})(\d+)(\d+)(\d+)\.(\d+):000/. It all works if you give everything explicit field widths, %8e%2H%2M%2S.%9N:000. Thanks for this explanation - it makes complete sense and in hindsight is completely obvious. To explain my confusion I did assume a little more DWIM given the following from the perldoc: --- begin --- Patterns This module uses a similar set of patterns to strftime. These patterns have been kept as close as possible to the original time-based patterns. ... %H The number of hours zero-padded to two digits. ... Precision can be changed for any and all the above values. For all but nanoseconds (%N), the precision is the zero-padding. --- end --- So my assumption was that the default precision for %H would be 2 if not specified. Of course, as has been pointed out, this only applies to output but its not explicitly stated that it doesn't apply to input scanning. Worth a doc patch or is it just me that finds this slightly confusing? Cheers, Andrew
Question regarding DateTime::Format::Duration
Hi all, I'm puzzling over the following which may just be a misunderstanding of the format string or something far more fundamental :-). I'm attempting to parse datetimes of the following format: hhmmss.n:000 For example, 11d 1h 34min 45sec 96000ns is 0011013445.96000:000 I had thought to use the following pattern: '%8e%H%M%S.%N:000' but it doesn't seem to want to play nice. In the example program attached I compare a handrolled version that calls DFD-normalise manually (unnecessary with this example and yes - I know all about base()) and the DFD-parse_duration version. Just for completeness I also strip off the leading zeros and try again with '%e%H%M%S.%N:000' and that doesn't seem to parse at all. Can anyone explain why parse_duration() gives me 11 days, 8044 minutes plus change? (that's around 5.5 extra days) ? Output: Processing string [0011013445.96000:000] Result using D::F::D and pattern [%8e%H%M%S.%N:000]: $VAR1 = bless( { 'seconds' = 5, 'minutes' = 8044, 'end_of_month' = 'wrap', 'nanoseconds' = 96000, 'days' = 11, 'months' = 0 }, 'DateTime::Duration' ); Hand rolled result: $VAR1 = bless( { 'seconds' = 45, 'minutes' = 94, 'end_of_month' = 'wrap', 'nanoseconds' = 96000, 'days' = 11, 'months' = 0 }, 'DateTime::Duration' ); Processing string [11013445.96000:000] Result using D::F::D and pattern [%e%H%M%S.%N:000]: $VAR1 = bless( { 'seconds' = 0, 'minutes' = 0, 'end_of_month' = 'wrap', 'nanoseconds' = 0, 'days' = 0, 'months' = 0 }, 'DateTime::Duration' ); Hand rolled result: $VAR1 = bless( { 'seconds' = 45, 'minutes' = 94, 'end_of_month' = 'wrap', 'nanoseconds' = 96000, 'days' = 11, 'months' = 0 }, 'DateTime::Duration' ); Cheers, Andrew test.pl Description: test.pl