Redis производительность на битовых массивах - PullRequest
0 голосов
/ 22 февраля 2019

В качестве теста я реализую простую программу для работы с битами как на чистом Python, так и на Redis.Я представляю свой битовый массив в виде наивного списка Python (хотя я прекрасно знаю о библиотеках, таких как bitstring ), и как строку в Redis (поскольку, согласно документации, «это возможно, используя специальныекоманды для обработки строковых значений как массива битов »).

Ниже инициализируем битовый массив в Python и Redis (обратите внимание, что первый вызов SETBIT создает структуру),затем измерьте значение 100000 битов равным 1, сначала в Python, а затем в Redis:

import random
import redis
db = redis.StrictRedis(host="localhost", port=6379, db=0)
print("Connected" if db.ping() else "Connection problem!")
db.flushdb()

m = 2 ** 23 # bit array size
n = 10 ** 5 # number of insertions

bit_array = [0] * m
db.setbit("bit_array", m, 0)

random.seed(42)
indexes = [random.randrange(m) for _ in range(n)]

%timeit for i in indexes: bit_array[i] = 1
%timeit for i in indexes: db.setbit("bit_array", i, 1)

Результат:

Connected
5.75 ms ± 849 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
4.71 s ± 70 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Итак, Redis кажется почти в 1000 раз медленнее чем наивная структура Python.Я что-то не так делаю?


Обновление

Следуя совету Жильвина Иосиуса, я инкапсулировал эти команды в конвейер:

%%timeit
pipe = db.pipeline()
for i in indexes:
    pipe.setbit("bit_array", i, 1)
pipe.execute()

Результат:

1.07 s ± 16.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Итак, это помогает, но Redis все еще на несколько порядков медленнее.

1 Ответ

0 голосов
/ 22 февраля 2019

Проблема в том, что вы управляете БД синхронно.После каждой операции setbit вы ожидаете ответа и только затем инициируете другой запрос.Чтобы избежать такого случая, используйте multi / pipe .Попробуйте создать конвейер, установите все ваши запросы в один пакет и только затем выполните его.Это зависит от того, какой клиент Python Redis вы используете, но это должно быть примерно так:

pipe = r.pipeline()

pipe.set('foo', 'bar')
pipe.set('baz')
pipe.execute()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...