Working with a smaller, bounded subset might help:

# reduce the working set size by intersecting with a smaller span
$total_span_set = $total_span_set->intersection(
  DateTime::Span->new(
    start  => DateTime->new( year => 2003, month => 1, day => 1 ),
    before => DateTime->new( year => 2003, month => 3, day => 1 )
  )
);

Also changing the set time zone inside a loop can be expensive.
It would be better to move the call to $dt_set->set_time_zone() to
outside of the loops.

Flávio S. Glock

2010/12/1 Per-Olof Jensen <per.jen...@bolderthinking.com>:
> I've been running into the issue of having a SpanSet being incredibly slow
> when doing a ->contains on a DateTime->now object.  I've tried spreading the
> spanset into an array of spans.  That becomes much faster, but only if there
> is no time zone set on those spans.  The moment I put time zones on those
> 'not unioned' spans I get a massive slowdown in computation time.  This is
> going into a large scale project, and I was hoping that this feature would
> be able to be used since it does exactly what I need it to do!
>
> Our goal is to take a group of spans and check if the time right now is
> within each span (basically a daily schedule across the globe).
>
> Here's a test program illustrating the problem I'm having.  I'm just
> wondering if there is any way to make the ->contains faster.
>
>
> #!/usr/bin/perl
>
> use DateTime::Event::Recurrence;
> use DateTime::SpanSet;
> use DateTime::Infinite;
> use DateTime::Set;
> use DateTime;
>
> my ($total_span_set, $start, $end, $spanset);
> my @array;
> my %tzhash = (
>    '1' => 'America/Halifax',
>    '2' => 'America/New_York',
>    '3' => 'America/Chicago',
>    '4' => 'America/Denver',
>    '5' => 'America/Los_Angeles',
>    '6' => 'America/Nome',
>    '7' => 'Pacific/Honolulu',
>    '8' => 'Asia/Tokyo',
> );
>
> $x = 7;
>
> while ($x > 0 ){
>
> # Make the set representing the work start times: M-F 9:00 and 13:00
> $start = DateTime::Event::Recurrence->weekly
>             ( days => $x%6+1, hours => 00 , minutes => 00);
> # Make the set representing the work end times: M-F 12:00 and 17:00
> $end   = DateTime::Event::Recurrence->weekly
>             ( days => $x%6+1, hours => 23, minutes => 59);
>
> # Build a spanset from the set of starting points and ending points
> $spanset = DateTime::SpanSet->from_sets
>                ( start_set => $start,
>                  end_set   => $end );
>
> if ($total_span_set){$total_span_set = $total_span_set->union($spanset)}
> else {$total_span_set = $spanset}
> push(@array, $spanset);
> $x--;
> }
> # Iterate from Thursday the 3rd to Monday the 6th
> my $it = $spanset->iterator
>           (start  =>
>            DateTime->new(year => 2003, month => 1, day => 3),
>            before =>
>            DateTime->new(year => 2003, month => 1, day => 7));
>
> while (my $span = $it->next) {
>    my ($st, $end) = ($span->start(), $span->end());
>    print $st->day_abbr, " ", $st->hour, " to ", $end->hour, "\n";
> }
>
> my $dt = DateTime->new(year => 2003, month => 2, day => 11, hour => 11);
>
>
> my $timer = DateTime->now;
>
> #Here I'm using the first way.  Using a spanet seems very slow on 'contains'
> regardless of having a timezone set or not for the span
> my $x = 3;
> while( $x ){
>    $dt->set_time_zone($tzhash{$x%6 + 1});
>    #Setting a time zone to the SpanSet doesn't seem to affect search time
>    $total_span_set->set_time_zone($tzhash{2});
>    if ($total_span_set->contains( $dt )){
>        print "Found time! \n";
>    }
> }
> $result = $timer - DateTime->now;
> print "Total time : ".$result->seconds."\n";
>
>
> #An array of spans, this seems to be very fast without timezones set
> $timer = DateTime->now;
> $x = 3;
> while( $x ){
>
>    foreach(@array){
>        #Setting a time zone to the SpanSet/Spans really hoses search time
>        $_->set_time_zone($tzhash{2});
>        if ($_->contains( $dt )){
>            print "Found time\n";
>        }
>    }
>    $x--;
> }
>
> $result = $timer - DateTime->now;
> print "Total time : ".$result->seconds."\n";
>
>
>
> --
> Per Jensen
> Bolder Thinking - Software Developer
>

Reply via email to