RE: DateTime performance

2012-05-03 Thread Andrew O'Brien
 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

2011-09-11 Thread Andrew O'Brien
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

2011-09-08 Thread Andrew O'Brien
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