summaryrefslogtreecommitdiff
path: root/benchmarks/basic_operations.py
diff options
context:
space:
mode:
authorChris Simpson <cjsimpson@gmail.com>2016-06-09 21:17:15 -0400
committerChris Simpson <cjsimpson@gmail.com>2016-06-12 18:57:34 -0400
commit8d8e86201ab589a3b97f4e2671d8b530e766a09b (patch)
treedc4c0425a7e8354e92eb4279e8acc6bc0d08ba9e /benchmarks/basic_operations.py
parentcb15dfcfa126f5e623b98c6bdf017941bf084cef (diff)
downloadredis-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.py197
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()