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"; }
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; }
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 ); }
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.