1#!/usr/bin/perl
2
3use 5.010;
4use warnings;
5use Redis;
6use RedisDB;
7use Redis::hiredis;
8use AnyEvent::Redis;
9use AnyEvent::Redis::RipeRedis;
10use Test::RedisDB;
11use Redis::Client;
12
13use Benchmark qw( cmpthese );
14
15say <<EOT;
16******************************************************************
17* Check source code to understand what this script benchmarking. *
18* Depending on your environment you may get different results,   *
19* e.g. hyper-threading may significantly decrease performance    *
20* of some modules.                                               *
21******************************************************************
22EOT
23
24say "Testing against";
25say "RedisDB:         ",            RedisDB->VERSION;
26say "Redis:           ",            Redis->VERSION;
27say "Redis::hiredis:  ",            Redis::hiredis->VERSION;
28say "Redis::Client:   ",            Redis::Client->VERSION;
29say "AnyEvent::Redis: ",            AnyEvent::Redis->VERSION;
30say "AnyEvent::Redis::RipeRedis: ", AnyEvent::Redis::RipeRedis->VERSION;
31
32my $srv;
33
34if ( $ENV{TEST_REDIS} ) {
35    my ( $host, $port ) = $ENV{TEST_REDIS} =~ /([^:]+):([0-9]+)/;
36    $srv = { host => $host, port => $port };
37}
38else {
39    $srv = Test::RedisDB->new;
40    $srv->{host} = '127.0.0.1';
41}
42
43my $redis = Redis->new(
44    server   => "$srv->{host}:$srv->{port}",
45    encoding => undef,
46
47    #    reconnect => 1,
48);
49my $redisdb = RedisDB->new( host => "$srv->{host}", port => $srv->{port} );
50say "redis-server: ", $redisdb->version;
51my $rediscl = Redis::Client->new( host => "$srv->{host}", port => $srv->{port} );
52my $hiredis = Redis::hiredis->new();
53$hiredis->connect( $srv->{host}, $srv->{port} );
54
55my $ae_redis = AnyEvent::Redis->new( host => "$srv->{host}", port => $srv->{port} );
56my $cv = $ae_redis->set( "RDB_AE_TEST", 1 );
57$cv->recv;
58
59$cv = AE::cv;
60my $ripe = AnyEvent::Redis::RipeRedis->new( host => "$srv->{host}", port => $srv->{port} );
61$ripe->set(
62    "RDB_RIPE_TEST",
63    1,
64    {
65        on_done => sub { $cv->send }
66    }
67);
68$cv->recv;
69
70sub sender {
71    my ( $cli, $num, $data ) = @_;
72    for ( 1 .. $num ) {
73        $cli->set( "key$_", $data );
74        $cli->get("key$_");
75    }
76}
77
78$redisdb->set( "RDB$_", "0123456789abcdef", RedisDB::IGNORE_REPLY ) for 1 .. 1000;
79
80say '';
81say "Testing setting/getting 16 bytes values";
82
83cmpthese 50, {
84    Redis => sub {
85        sender( $redis, 1000, "0123456789abcdef" );
86    },
87    hiredis => sub {
88        sender( $hiredis, 1000, "0123456789abcdef" );
89    },
90    RedisDB => sub {
91        sender( $redisdb, 1000, "0123456789abcdef" );
92    },
93    "Redis::Client" => sub {
94        sender( $rediscl, 1000, "0123456789abcdef" );
95    },
96    "RedisDB Pipelining" => sub {
97        for ( 1 .. 1000 ) {
98            $redisdb->set( "RDB$_", "0123456789abcdef", RedisDB::IGNORE_REPLY );
99            $redisdb->get( "RDB$_", RedisDB::IGNORE_REPLY );
100        }
101        $redisdb->mainloop;
102    },
103    "Redis Pipelining" => sub {
104        for ( 1 .. 1000 ) {
105            $redis->set( "RDB$_", "0123456789abcdef", sub { } );
106            $redis->get( "RDB$_", sub { } );
107        }
108        $redis->wait_all_responses;
109    },
110    "hiredis pipelining" => sub {
111        for ( 1 .. 1000 ) {
112            $hiredis->append_command("SET RDB$_ 0123456789abcdef");
113            $hiredis->append_command("GET RDB$_");
114        }
115        my %res;
116        for ( 1 .. 2000 ) {
117            $res{ $hiredis->get_reply }++;
118        }
119    },
120    "AE::Redis" => sub {
121        my $done = AE::cv;
122        my $cnt;
123        AE::postpone {
124            for ( 1 .. 1000 ) {
125                $ae_redis->set( "RDB$_", "0123456789abcdef", sub { } );
126                $ae_redis->get( "RDB$_", sub { $done->send if ++$cnt == 1000 } );
127            }
128        };
129        $done->recv;
130    },
131    "AE::R::RipeRedis" => sub {
132        my $done = AE::cv;
133        my $cnt;
134        AE::postpone {
135            for ( 1 .. 1000 ) {
136                $ripe->set( "RDB$_", "0123456789abcdef" );
137                $ripe->get(
138                    "RDB$_",
139                    {
140                        on_done => sub { $done->send if ++$cnt == 1000 }
141                    }
142                );
143            }
144        };
145        $done->recv;
146    },
147};
148
149say '';
150say "Testing setting/getting 2K values";
151
152cmpthese 150, {
153    Redis => sub {
154        sender( $redis, 300, "0123456789abcdef" x 128 );
155    },
156    hiredis => sub {
157        sender( $hiredis, 300, "0123456789abcdef" x 128 );
158    },
159    RedisDB => sub {
160        sender( $redisdb, 300, "0123456789abcdef" x 128 );
161    },
162    "Redis::Client" => sub {
163        sender( $rediscl, 300, "0123456789abcdef" x 128 );
164    },
165};
166
167say '';
168say "Testing setting/getting 16K values";
169
170cmpthese 150, {
171    Redis => sub {
172        sender( $redis, 100, "0123456789abcdef" x 1024 );
173    },
174    hiredis => sub {
175        sender( $hiredis, 100, "0123456789abcdef" x 1024 );
176    },
177    RedisDB => sub {
178        sender( $redisdb, 100, "0123456789abcdef" x 1024 );
179    },
180    "Redis::Client" => sub {
181        sender( $rediscl, 100, "0123456789abcdef" x 1024 );
182    },
183};
184