Skip to content
This repository has been archived by the owner on Feb 21, 2023. It is now read-only.

reduce encode_command cost about 60%+ #397

Merged
merged 2 commits into from
Mar 27, 2018
Merged

reduce encode_command cost about 60%+ #397

merged 2 commits into from
Mar 27, 2018

Conversation

fuchaoqun
Copy link
Contributor

@fuchaoqun fuchaoqun commented Mar 22, 2018

import time

_converters = {
    bytes: lambda val: val,
    bytearray: lambda val: val,
    str: lambda val: val.encode(),
    int: lambda val: b'%d' % val,
    float: lambda val: b'%r' % val,
}

def encode_command(*args):
    """Encodes arguments into redis bulk-strings array.

    Raises TypeError if any of args not of bytearray, bytes, float, int, or str
    type.
    """
    buf = bytearray(b'*%d\r\n' % len(args))

    try:
        for arg in args:
            barg = _converters[type(arg)](arg)
            buf.extend(b'$%d\r\n%s\r\n' % (len(barg), barg))
    except:
        raise TypeError("Argument {!r} expected to be of bytearray, bytes,"
                        " float, int, or str type".format(arg))
    return buf


_converters_old = {
    bytes: lambda val: val,
    bytearray: lambda val: val,
    str: lambda val: val.encode('utf-8'),
    int: lambda val: str(val).encode('utf-8'),
    float: lambda val: str(val).encode('utf-8'),
}


def _bytes_len(sized):
    return str(len(sized)).encode('utf-8')


def encode_command_old(*args):
    """Encodes arguments into redis bulk-strings array.

    Raises TypeError if any of args not of bytearray, bytes, float, int, or str
    type.
    """
    buf = bytearray()

    def add(data):
        return buf.extend(data + b'\r\n')

    add(b'*' + _bytes_len(args))
    for arg in args:
        if type(arg) in _converters:
            barg = _converters_old[type(arg)](arg)
            add(b'$' + _bytes_len(barg))
            add(barg)
        else:
            raise TypeError("Argument {!r} expected to be of bytearray, bytes,"
                            " float, int, or str type".format(arg))
    return buf



t1 = time.time()
for i in range(10000):
    foo = encode_command(123, "abc", 4.567, b'890jqk')
print(time.time()-t1)
t1 = time.time()
for i in range(10000):
    bar = encode_command_old(123, "abc", 4.567, b'890jqk')
print(time.time()-t1)

assert foo == bar

on my mbp, the result is:

0.04150104522705078
0.09163022041320801

@codecov
Copy link

codecov bot commented Mar 22, 2018

Codecov Report

Merging #397 into master will decrease coverage by 0.08%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #397      +/-   ##
==========================================
- Coverage   96.83%   96.75%   -0.09%     
==========================================
  Files          54       54              
  Lines        7452     7447       -5     
  Branches      526      525       -1     
==========================================
- Hits         7216     7205      -11     
- Misses        171      175       +4     
- Partials       65       67       +2
Impacted Files Coverage Δ
aioredis/util.py 95% <100%> (-0.21%) ⬇️
tests/sentinel_failover_test.py 85.71% <0%> (-3.01%) ⬇️
aioredis/sentinel/pool.py 78.57% <0%> (-0.76%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 729da7b...fb6c4bf. Read the comment docs.

@popravich popravich merged commit 51d5aa1 into aio-libs-abandoned:master Mar 27, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants