Simon Wistow (deflatermouse) wrote,
Simon Wistow
deflatermouse

Cache in Hand

Oh God. The title puns are getting worse and worse.

I started playing around with caching strategies for Data::ICal::DateTime and ended up with these three strategies.

All of them assume this function

    sub get_name {                                                                       
        my $ics   = shift;
        my $span  = shift;
        my $start = ($span->start_is_open)? "infinite" : $span->start->epoch;
        my $end   = ($span->end_is_open)?   "infinite" : $span->end->epoch;
        return "$ics-$start-$end";
    }  

Memoize:

    tie my %cache => 'DB_File', $filename, O_RDWR|O_CREAT, 0666;                         
    memoize('events', NORMALIZER => 'get_name',                                          
                      SCALAR_CACHE => [HASH => \%cache]);                                
                                                                                     
    my @events = events($ics, $span);                                                    
                                                                                     
    sub events {                                                                         
        my $ics  = shift;                                                            
        my $span = shift;                                                            
        my $cal  = Data::ICal->new( filename => $ics );                              
        return $cal->events;                                                         
    }                                                                                    
                                                                                     

Pixie:

    my $pixie   = Pixie->new->connect('bdb:cache/cache.db');                               
    my $name   = get_name($ics, $set);                                                     
    my $events = $pixie->get_object_named($name);                                        
                                                                                         
    my @events;                                                                          
    if ($events) {                                                                       
        @events = @$events;                                                              
    } else {                                                                             
        my $cal = Data::ICal->new( filename => $ics);                                    
        @events = $cal->events($set);                                                    
        my $object = bless \@events, "Random";                                           
        $pixie->bind_name( $name => $object );                                           
    }        

Storable:

    my @events;
    my $name  = get_name($ics, $set);  
    my $cache = "cache/$name.cache";
    if (-e $cache) {                                                              
        # stat to check the cache is still valid...                                          
        @events = @{ Storable::retrieve( $cache ) };
    } else {
        my $cal = Data::ICal->new( filename => $ics );
        @events = $cal->events($span);
        Storable::store \@events, $cache;
    }

Benchmarked that gives -

 Benchmark: timing 1000 iterations of memoize, pixie, storable... 
   memoize:  4 wallclock secs ( 3.47 usr +  0.06 sys =  3.53 CPU) @ 283.29/s (n=1000)
     pixie: 13 wallclock secs (11.57 usr +  0.11 sys = 11.68 CPU) @ 85.62/s (n=1000) 
  storable:  4 wallclock secs ( 3.91 usr +  0.09 sys =  4.00 CPU) @ 250.00/s (n=1000)
               Rate    pixie storable  memoize
    pixie    85.6/s       --     -66%     -70% 
    storable  250/s     192%       --     -12%
    memoize   283/s     231%      13%       --  

Which is pretty respectable.

The full script I used to do this is here.

Tags: benchmark, caching, datetime, ical, oh god, pixie, puns, respectable, storable
Subscribe
  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 0 comments