diff options
author | Chris Simpson <cjsimpson@gmail.com> | 2016-06-09 21:17:15 -0400 |
---|---|---|
committer | Chris Simpson <cjsimpson@gmail.com> | 2016-06-12 18:57:34 -0400 |
commit | 8d8e86201ab589a3b97f4e2671d8b530e766a09b (patch) | |
tree | dc4c0425a7e8354e92eb4279e8acc6bc0d08ba9e /benchmarks/basic_operations.py | |
parent | cb15dfcfa126f5e623b98c6bdf017941bf084cef (diff) | |
download | redis-py-8d8e86201ab589a3b97f4e2671d8b530e766a09b.tar.gz |
Cache Token objects to improve performance.
The Token class now contains a cache of tokens, and each token stores its encoded value.
In Python 3 this prevents encoding the Token commands (get, set, incr, etc...) repeatly.
There is also a smaller performance improvement by creating fewer objects.
A very basic benchmark script was also added.
Diffstat (limited to 'benchmarks/basic_operations.py')
-rw-r--r-- | benchmarks/basic_operations.py | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/benchmarks/basic_operations.py b/benchmarks/basic_operations.py new file mode 100644 index 0000000..cb7f3f2 --- /dev/null +++ b/benchmarks/basic_operations.py @@ -0,0 +1,197 @@ +from __future__ import print_function +import redis +import time +import sys +from functools import wraps +from argparse import ArgumentParser + +if sys.version_info[0] == 3: + long = int + +def parse_args(): + parser = ArgumentParser() + parser.add_argument('-n', + type=int, + help='Total number of requests (default 100000)', + default=100000) + parser.add_argument('-P', + type=int, + help=('Pipeline <numreq> requests.' + ' Default 1 (no pipeline).'), + default=1) + parser.add_argument('-s', + type=int, + help='Data size of SET/GET value in bytes (default 2)', + default=2) + + args = parser.parse_args() + return args + +def run(): + args = parse_args() + r = redis.StrictRedis() + r.flushall() + set_str(conn=r, num=args.n, pipeline_size=args.P, data_size=args.s) + set_int(conn=r, num=args.n, pipeline_size=args.P, data_size=args.s) + get_str(conn=r, num=args.n, pipeline_size=args.P, data_size=args.s) + get_int(conn=r, num=args.n, pipeline_size=args.P, data_size=args.s) + incr(conn=r, num=args.n, pipeline_size=args.P, data_size=args.s) + lpush(conn=r, num=args.n, pipeline_size=args.P, data_size=args.s) + lrange_300(conn=r, num=args.n, pipeline_size=args.P, data_size=args.s) + lpop(conn=r, num=args.n, pipeline_size=args.P, data_size=args.s) + hmset(conn=r, num=args.n, pipeline_size=args.P, data_size=args.s) + + +def timer(func): + @wraps(func) + def wrapper(*args, **kwargs): + start = time.clock() + ret = func(*args, **kwargs) + duration = time.clock() - start + if 'num' in kwargs: + count = kwargs['num'] + else: + count = args[1] + print('{0} - {1} Requests'.format(func.__name__, count)) + print('Duration = {}'.format(duration)) + print('Rate = {}'.format(count/duration)) + print('') + return ret + return wrapper + + +@timer +def set_str(conn, num, pipeline_size, data_size): + if pipeline_size > 1: + conn = conn.pipeline() + + format_str = '{:0<%d}' % data_size + set_data = format_str.format('a') + for i in range(num): + conn.set('set_str:%d' % i, set_data) + if pipeline_size > 1 and i % pipeline_size == 0: + conn.execute() + + if pipeline_size > 1: + conn.execute() + + +@timer +def set_int(conn, num, pipeline_size, data_size): + if pipeline_size > 1: + conn = conn.pipeline() + + format_str = '{:0<%d}' % data_size + set_data = int(format_str.format('1')) + for i in range(num): + conn.set('set_int:%d' % i, set_data) + if pipeline_size > 1 and i % pipeline_size == 0: + conn.execute() + + if pipeline_size > 1: + conn.execute() + + +@timer +def get_str(conn, num, pipeline_size, data_size): + if pipeline_size > 1: + conn = conn.pipeline() + + for i in range(num): + conn.get('set_str:%d' % i) + if pipeline_size > 1 and i % pipeline_size == 0: + conn.execute() + + if pipeline_size > 1: + conn.execute() + + +@timer +def get_int(conn, num, pipeline_size, data_size): + if pipeline_size > 1: + conn = conn.pipeline() + + for i in range(num): + conn.get('set_int:%d' % i) + if pipeline_size > 1 and i % pipeline_size == 0: + conn.execute() + + if pipeline_size > 1: + conn.execute() + + +@timer +def incr(conn, num, pipeline_size, *args, **kwargs): + if pipeline_size > 1: + conn = conn.pipeline() + + for i in range(num): + conn.incr('incr_key') + if pipeline_size > 1 and i % pipeline_size == 0: + conn.execute() + + if pipeline_size > 1: + conn.execute() + + +@timer +def lpush(conn, num, pipeline_size, data_size): + if pipeline_size > 1: + conn = conn.pipeline() + + format_str = '{:0<%d}' % data_size + set_data = int(format_str.format('1')) + for i in range(num): + conn.lpush('lpush_key', set_data) + if pipeline_size > 1 and i % pipeline_size == 0: + conn.execute() + + if pipeline_size > 1: + conn.execute() + + +@timer +def lrange_300(conn, num, pipeline_size, data_size): + if pipeline_size > 1: + conn = conn.pipeline() + + for i in range(num): + conn.lrange('lpush_key', i, i+300) + if pipeline_size > 1 and i % pipeline_size == 0: + conn.execute() + + if pipeline_size > 1: + conn.execute() + + +@timer +def lpop(conn, num, pipeline_size, data_size): + if pipeline_size > 1: + conn = conn.pipeline() + for i in range(num): + conn.lpop('lpush_key') + if pipeline_size > 1 and i % pipeline_size == 0: + conn.execute() + if pipeline_size > 1: + conn.execute() + + +@timer +def hmset(conn, num, pipeline_size, data_size): + if pipeline_size > 1: + conn = conn.pipeline() + + set_data = {'str_value': 'string', + 'int_value': 123456, + 'long_value': long(123456), + 'float_value': 123456.0} + for i in range(num): + conn.hmset('hmset_key', set_data) + if pipeline_size > 1 and i % pipeline_size == 0: + conn.execute() + + if pipeline_size > 1: + conn.execute() + +if __name__ == '__main__': + run() |