use strict; use warnings; use Benchmark qw(); use Test::More; plan tests => 40; use_ok('Cache::MemoryCache'); use_ok('Cache::Memcached'); # use_ok('Cache::Memcached::Fast'); use_ok('Cache::Memcached::libmemcached'); use_ok('Cache::FastMmap'); use_ok('CHI'); use_ok('CHI::Driver::Memcached'); use_ok('CHI::Driver::FastMmap'); use_ok('CHI::Driver::Memory'); use Data::UUID; use Time::HiRes qw(time); use vars qw($ITER $LASTID $cmem $cfm $cmcl $cmclip $cmc $chimem $chimmap $chimc $chimcl $chimclip $chil1); my $uuidgen = new Data::UUID; my $memcached_servers = [ "localhost:11211" ]; my $memcached_socket = [ "/var/tmp/memcached.socket" ]; $ITER = 1; $LASTID = 1; my %testdata = ( 'keys' => [ map { $uuidgen->create_str() } 1..2**10 ], 'small' => [ map { $uuidgen->create() } 1..2**10 ], 'medium' => [ map { $uuidgen->create() x 10 } 1..2**10 ], 'large' => [ map { $uuidgen->create() x 100 } 1..2**10 ], ); sub cachetest { my $cache = shift; my $count = shift || 100000; my $ratio = shift || 10; # $ratio times get per set my $dataset = shift || 'small'; # dataset to use (size of values) my $invalid = 0; my $i = 0; while ($i++ < $count) { my $id = $i & 1023; my ($key, $value) = ($testdata{'keys'}->[$id], $testdata{$dataset}->[$id]); $cache->set($key, $value); foreach (1..$ratio) { my $val = $cache->get($key); $invalid++ unless (defined($val) && $val eq $value); last unless $i++ > $count; } } ok($invalid == 0, "benchtest $cache is ok"); } sub time_cache { my ($name, $cache, $count, $ratio, $dataset) = @_; my $start = time(); # diag("Starting test for $name: $start, $count, $ratio, $dataset (on $cache)"); cachetest($cache, $count, $ratio, $dataset); diag(sprintf("$name with $count (ratio 1:$ratio) dataset $dataset took %.6f sec(s)", time() - $start)); } sub time_all_caches { my ($count, $ratio, $dataset) = @_; diag("### Starting timing series with count $count, set:get ratio 1:$ratio, dataset $dataset"); # time_cache('Cache::Memory', $cmem, $count, $ratio, $dataset); time_cache('Cache::Memcached::libmemcached', $cmcl, $count, $ratio, $dataset); time_cache('Cache::Memcached::libmemcached (ip)', $cmclip, $count, $ratio, $dataset); # time_cache('Cache::Memcached', $cmc, $count, $ratio, $dataset); time_cache('Cache::FastMmap', $cfm, $count, $ratio, $dataset); # time_cache('CHI::Driver::Memcached', $chimc, $count, $ratio, $dataset); time_cache('CHI::Driver::Memcached::libmemcached', $chimcl, $count, $ratio, $dataset); time_cache('CHI::Driver::Memcached::libmemcached (ip)', $chimclip, $count, $ratio, $dataset); time_cache('CHI::Driver::FastMmap', $chimmap, $count, $ratio, $dataset); time_cache('CHI::Driver::Memory', $chimem, $count, $ratio, $dataset); time_cache('CHI::Mixed::L1', $chil1, $count, $ratio, $dataset); } sub benchtest { my $cache = shift; my $ratio = shift || 10; # $ratio times get per set my $dataset = shift || 'small'; # $ratio times get per set if (++$ITER > $ratio) { $ITER = 1; $LASTID = rand(1024); }; my ($key, $value) = ($testdata{keys}->[$LASTID], $testdata{$dataset}->[$LASTID]); if ($ITER == 1) { $cache->set($key, $value); } else { my $val = $cache->get($key); } } $cmem = Cache::MemoryCache->new({}); ok($cmem, "Cache::MemoryCache initialized"); $cmcl = Cache::Memcached::libmemcached->new({ servers => $memcached_socket, compress_threshold => 10000 }); ok($cmcl, "Cache::Memcached::libmemcached initialized"); $cmclip = Cache::Memcached::libmemcached->new({ servers => $memcached_servers, compress_threshold => 10000 }); ok($cmclip, "Cache::Memcached::libmemcached (ip) initialized"); $cmc = Cache::Memcached->new({ servers => $memcached_socket, compress_threshold => 10000 }); ok($cmc, "Cache::Memcached initialized"); $cfm = Cache::FastMmap->new({ share_file => "/tmp/sharefile-$$", cache_size => '1m', expire_time => '1 hour', }); ok($cfm, "Cache::FastMmap initialized"); $chimc = CHI->new( driver => 'Memcached', namespace => '', servers => $memcached_socket, compress_threshold => 10000 ); ok($chimc, "CHI::Driver::Memcached initialized"); $chimcl = CHI->new( driver => 'Memcached::libmemcached', namespace => '', servers => $memcached_socket, compress_threshold => 10000 ); ok($chimcl, "CHI::Driver::Memcached::libmemcached initialized"); $chimclip = CHI->new( driver => 'Memcached::libmemcached', namespace => '', servers => $memcached_servers, compress_threshold => 10000 ); ok($chimclip, "CHI::Driver::Memcached::libmemcached (ip) initialized"); $chimmap = CHI->new( driver => 'FastMmap', root_dir => '/tmp', namespace => '', cache_size => '1m', compress_threshold => 10000 ); ok($chimmap, "CHI::Driver::FastMmap initialized"); $chimem = CHI->new( driver => 'Memory', global => 1, namespace => '', compress_threshold => 10000, max_size => 16384000 ); ok($chimem, "CHI::Driver::Memory initialized"); $chil1 = CHI->new( driver => 'Memcached::libmemcached', namespace => '', servers => $memcached_servers, compress_threshold => 10000, l1_cache => { driver => 'Memory', global => 1, max_size => 16384000 } ); ok($chil1, "CHI Mixed Memory + L1 Memcached (ip) initialized"); time_all_caches(1000, 1, 'medium'); time_all_caches(1000, 10, 'medium'); time_all_caches(1000, 100, 'medium'); sub bench_all_caches { my $count = shift || -5; ### negative count for seconds to run my $ratio = shift; my $dataset = shift; diag("Benchmarking caches with ratio 1:$ratio and $dataset values"); Benchmark::cmpthese($count, { 'C:Mc:l' => sub { benchtest($cmcl, $ratio, $dataset); }, 'C:Mc:lIP' => sub { benchtest($cmclip, $ratio, $dataset); }, # 'C:Mc:F' => sub { benchtest($cmcf, $ratio, $dataset); }, # 'C:Mc' => sub { benchtest($cmc, $ratio, $dataset); }, 'C:FMmap' => sub { benchtest($cfm, $ratio, $dataset); }, # 'C:Mem' => sub { benchtest($cmem, $ratio, $dataset); }, 'CHI:Mem' => sub { benchtest($chimem, $ratio, $dataset); }, 'CHI:FMmap' => sub { benchtest($chimmap, $ratio, $dataset); }, # 'CHI:Mc' => sub { benchtest($chimc, $ratio, $dataset); }, 'CHI:Mc:l' => sub { benchtest($chimcl, $ratio, $dataset); }, 'CHI:Mc:lIP' => sub { benchtest($chimclip, $ratio, $dataset); }, 'CHI:L1' => sub { benchtest($chil1, $ratio, $dataset); }, }); } bench_all_caches(-5, 10, 'small'); bench_all_caches(-5, 10, 'medium'); bench_all_caches(-5, 10, 'large'); bench_all_caches(-5, 1, 'medium'); bench_all_caches(-5, 10, 'medium'); bench_all_caches(-5, 100, 'medium');