diff options
author | Andy McCurdy <andy@andymccurdy.com> | 2016-06-14 13:49:07 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-06-14 13:49:07 -0400 |
commit | 0531abed1ee5caa010d5916e1c09f5c7d0b1c49d (patch) | |
tree | e7a7cdfb4c2949ab8d490c6b3869b403e2e1a067 /redis | |
parent | 98e1133422b8514656e244ae5d332e65aa97124e (diff) | |
parent | 138836c1be4f8f1ffef20ce2d2e723b4aba26d66 (diff) | |
download | redis-py-0531abed1ee5caa010d5916e1c09f5c7d0b1c49d.tar.gz |
Merge pull request #751 from cjsimpson/token-cache
Improve performance for Python 3.x
Diffstat (limited to 'redis')
-rwxr-xr-x | redis/client.py | 53 | ||||
-rwxr-xr-x | redis/connection.py | 24 |
2 files changed, 48 insertions, 29 deletions
diff --git a/redis/client.py b/redis/client.py index d84c8b3..76e5fd7 100755 --- a/redis/client.py +++ b/redis/client.py @@ -787,7 +787,8 @@ class StrictRedis(object): instance is promoted to a master instead. """ if host is None and port is None: - return self.execute_command('SLAVEOF', Token('NO'), Token('ONE')) + return self.execute_command('SLAVEOF', Token.get_token('NO'), + Token.get_token('ONE')) return self.execute_command('SLAVEOF', host, port) def slowlog_get(self, num=None): @@ -1362,10 +1363,10 @@ class StrictRedis(object): pieces = [name] if by is not None: - pieces.append(Token('BY')) + pieces.append(Token.get_token('BY')) pieces.append(by) if start is not None and num is not None: - pieces.append(Token('LIMIT')) + pieces.append(Token.get_token('LIMIT')) pieces.append(start) pieces.append(num) if get is not None: @@ -1374,18 +1375,18 @@ class StrictRedis(object): # values. We can't just iterate blindly because strings are # iterable. if isinstance(get, basestring): - pieces.append(Token('GET')) + pieces.append(Token.get_token('GET')) pieces.append(get) else: for g in get: - pieces.append(Token('GET')) + pieces.append(Token.get_token('GET')) pieces.append(g) if desc: - pieces.append(Token('DESC')) + pieces.append(Token.get_token('DESC')) if alpha: - pieces.append(Token('ALPHA')) + pieces.append(Token.get_token('ALPHA')) if store is not None: - pieces.append(Token('STORE')) + pieces.append(Token.get_token('STORE')) pieces.append(store) if groups: @@ -1409,9 +1410,9 @@ class StrictRedis(object): """ pieces = [cursor] if match is not None: - pieces.extend([Token('MATCH'), match]) + pieces.extend([Token.get_token('MATCH'), match]) if count is not None: - pieces.extend([Token('COUNT'), count]) + pieces.extend([Token.get_token('COUNT'), count]) return self.execute_command('SCAN', *pieces) def scan_iter(self, match=None, count=None): @@ -1440,9 +1441,9 @@ class StrictRedis(object): """ pieces = [name, cursor] if match is not None: - pieces.extend([Token('MATCH'), match]) + pieces.extend([Token.get_token('MATCH'), match]) if count is not None: - pieces.extend([Token('COUNT'), count]) + pieces.extend([Token.get_token('COUNT'), count]) return self.execute_command('SSCAN', *pieces) def sscan_iter(self, name, match=None, count=None): @@ -1472,9 +1473,9 @@ class StrictRedis(object): """ pieces = [name, cursor] if match is not None: - pieces.extend([Token('MATCH'), match]) + pieces.extend([Token.get_token('MATCH'), match]) if count is not None: - pieces.extend([Token('COUNT'), count]) + pieces.extend([Token.get_token('COUNT'), count]) return self.execute_command('HSCAN', *pieces) def hscan_iter(self, name, match=None, count=None): @@ -1507,9 +1508,9 @@ class StrictRedis(object): """ pieces = [name, cursor] if match is not None: - pieces.extend([Token('MATCH'), match]) + pieces.extend([Token.get_token('MATCH'), match]) if count is not None: - pieces.extend([Token('COUNT'), count]) + pieces.extend([Token.get_token('COUNT'), count]) options = {'score_cast_func': score_cast_func} return self.execute_command('ZSCAN', *pieces, **options) @@ -1685,7 +1686,7 @@ class StrictRedis(object): score_cast_func) pieces = ['ZRANGE', name, start, end] if withscores: - pieces.append(Token('WITHSCORES')) + pieces.append(Token.get_token('WITHSCORES')) options = { 'withscores': withscores, 'score_cast_func': score_cast_func @@ -1705,7 +1706,7 @@ class StrictRedis(object): raise RedisError("``start`` and ``num`` must both be specified") pieces = ['ZRANGEBYLEX', name, min, max] if start is not None and num is not None: - pieces.extend([Token('LIMIT'), start, num]) + pieces.extend([Token.get_token('LIMIT'), start, num]) return self.execute_command(*pieces) def zrevrangebylex(self, name, max, min, start=None, num=None): @@ -1721,7 +1722,7 @@ class StrictRedis(object): raise RedisError("``start`` and ``num`` must both be specified") pieces = ['ZREVRANGEBYLEX', name, max, min] if start is not None and num is not None: - pieces.extend([Token('LIMIT'), start, num]) + pieces.extend([Token.get_token('LIMIT'), start, num]) return self.execute_command(*pieces) def zrangebyscore(self, name, min, max, start=None, num=None, @@ -1743,9 +1744,9 @@ class StrictRedis(object): raise RedisError("``start`` and ``num`` must both be specified") pieces = ['ZRANGEBYSCORE', name, min, max] if start is not None and num is not None: - pieces.extend([Token('LIMIT'), start, num]) + pieces.extend([Token.get_token('LIMIT'), start, num]) if withscores: - pieces.append(Token('WITHSCORES')) + pieces.append(Token.get_token('WITHSCORES')) options = { 'withscores': withscores, 'score_cast_func': score_cast_func @@ -1803,7 +1804,7 @@ class StrictRedis(object): """ pieces = ['ZREVRANGE', name, start, end] if withscores: - pieces.append(Token('WITHSCORES')) + pieces.append(Token.get_token('WITHSCORES')) options = { 'withscores': withscores, 'score_cast_func': score_cast_func @@ -1829,9 +1830,9 @@ class StrictRedis(object): raise RedisError("``start`` and ``num`` must both be specified") pieces = ['ZREVRANGEBYSCORE', name, max, min] if start is not None and num is not None: - pieces.extend([Token('LIMIT'), start, num]) + pieces.extend([Token.get_token('LIMIT'), start, num]) if withscores: - pieces.append(Token('WITHSCORES')) + pieces.append(Token.get_token('WITHSCORES')) options = { 'withscores': withscores, 'score_cast_func': score_cast_func @@ -1865,10 +1866,10 @@ class StrictRedis(object): weights = None pieces.extend(keys) if weights: - pieces.append(Token('WEIGHTS')) + pieces.append(Token.get_token('WEIGHTS')) pieces.extend(weights) if aggregate: - pieces.append(Token('AGGREGATE')) + pieces.append(Token.get_token('AGGREGATE')) pieces.append(aggregate) return self.execute_command(*pieces) diff --git a/redis/connection.py b/redis/connection.py index f0e28e3..27db42a 100755 --- a/redis/connection.py +++ b/redis/connection.py @@ -65,10 +65,27 @@ class Token(object): hard-coded arguments are wrapped in this class so we know not to apply and encoding rules on them. """ + + _cache = {} + + @classmethod + def get_token(cls, value): + "Gets a cached token object or creates a new one if not already cached" + + # Use try/except because after running for a short time most tokens + # should already be cached + try: + return cls._cache[value] + except KeyError: + token = Token(value) + cls._cache[value] = token + return token + def __init__(self, value): if isinstance(value, Token): value = value.value self.value = value + self.encoded_value = b(value) def __repr__(self): return self.value @@ -586,7 +603,7 @@ class Connection(object): def encode(self, value): "Return a bytestring representation of the value" if isinstance(value, Token): - return b(value.value) + return value.encoded_value elif isinstance(value, bytes): return value elif isinstance(value, (int, long)): @@ -609,9 +626,10 @@ class Connection(object): # to prevent them from being encoded. command = args[0] if ' ' in command: - args = tuple([Token(s) for s in command.split(' ')]) + args[1:] + args = tuple([Token.get_token(s) + for s in command.split()]) + args[1:] else: - args = (Token(command),) + args[1:] + args = (Token.get_token(command),) + args[1:] buff = SYM_EMPTY.join( (SYM_STAR, b(str(len(args))), SYM_CRLF)) |