You need to sign in or sign up before continuing.
Unverified Commit bcae7708 authored by Filipe Oliveira (Redis)'s avatar Filipe Oliveira (Redis) Committed by GitHub
Browse files

Optimize LREM, LPOS, LINSERT, LINDEX: Avoid N-1 sdslen() calls on listTypeEqual (#13529)

This is a very easy optimization, that avoids duplicate computation of
the object length for LREM, LPOS, LINSERT na LINDEX.

We can see that sdslen takes 7.7% of the total CPU cycles of the
benchmarks.

Function Stack | CPU Time: Total | CPU Time: Self | Module | Function
(Full) | Source File | Start Address
-- | -- | -- | -- | -- | -- | --
listTypeEqual | 15.50% | 2.346s | redis-server | listTypeEqual |
t_list.c | 0x845dd
sdslen | 7.70% | 2.300s | redis-server | sdslen | sds.h | 0x845e4

Preliminary data showcases 4% improvement in the achievable ops/sec of
LPOS in string elements, and 2% in int elements.
parent bf802b07
......@@ -2748,7 +2748,7 @@ robj *listTypeGet(listTypeEntry *entry);
unsigned char *listTypeGetValue(listTypeEntry *entry, size_t *vlen, long long *lval);
void listTypeInsert(listTypeEntry *entry, robj *value, int where);
void listTypeReplace(listTypeEntry *entry, robj *value);
int listTypeEqual(listTypeEntry *entry, robj *o);
int listTypeEqual(listTypeEntry *entry, robj *o, size_t object_len);
void listTypeDelete(listTypeIterator *iter, listTypeEntry *entry);
robj *listTypeDup(robj *o);
void listTypeDelRange(robj *o, long start, long stop);
......
......@@ -383,12 +383,12 @@ int listTypeReplaceAtIndex(robj *o, int index, robj *value) {
}
/* Compare the given object with the entry at the current position. */
int listTypeEqual(listTypeEntry *entry, robj *o) {
int listTypeEqual(listTypeEntry *entry, robj *o, size_t object_len) {
serverAssertWithInfo(NULL,o,sdsEncodedObject(o));
if (entry->li->encoding == OBJ_ENCODING_QUICKLIST) {
return quicklistCompare(&entry->entry,o->ptr,sdslen(o->ptr));
return quicklistCompare(&entry->entry,o->ptr,object_len);
} else if (entry->li->encoding == OBJ_ENCODING_LISTPACK) {
return lpCompare(entry->lpe,o->ptr,sdslen(o->ptr));
return lpCompare(entry->lpe,o->ptr,object_len);
} else {
serverPanic("Unknown list encoding");
}
......@@ -538,8 +538,9 @@ void linsertCommand(client *c) {
/* Seek pivot from head to tail */
iter = listTypeInitIterator(subject,0,LIST_TAIL);
const size_t object_len = sdslen(c->argv[3]->ptr);
while (listTypeNext(iter,&entry)) {
if (listTypeEqual(&entry,c->argv[3])) {
if (listTypeEqual(&entry,c->argv[3],object_len)) {
listTypeInsert(&entry,c->argv[4],where);
inserted = 1;
break;
......@@ -999,8 +1000,9 @@ void lposCommand(client *c) {
listTypeEntry entry;
long llen = listTypeLength(o);
long index = 0, matches = 0, matchindex = -1, arraylen = 0;
const size_t ele_len = sdslen(ele->ptr);
while (listTypeNext(li,&entry) && (maxlen == 0 || index < maxlen)) {
if (listTypeEqual(&entry,ele)) {
if (listTypeEqual(&entry,ele,ele_len)) {
matches++;
matchindex = (direction == LIST_TAIL) ? index : llen - index - 1;
if (matches >= rank) {
......@@ -1052,8 +1054,9 @@ void lremCommand(client *c) {
}
listTypeEntry entry;
const size_t object_len = sdslen(c->argv[3]->ptr);
while (listTypeNext(li,&entry)) {
if (listTypeEqual(&entry,obj)) {
if (listTypeEqual(&entry,obj,object_len)) {
listTypeDelete(li, &entry);
server.dirty++;
removed++;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment