Skip to content

Commit b857928

Browse files
Optimize deferred replies to use shared objects instead of sprintf (redis#10334)
Avoid sprintf/ll2string on setDeferredAggregateLen()/addReplyLongLongWithPrefix() when we can used shared objects. In some pipelined workloads this achieves about 10% improvement. Co-authored-by: Oran Agra <[email protected]>
1 parent a7179e7 commit b857928

File tree

3 files changed

+35
-3
lines changed

3 files changed

+35
-3
lines changed

src/networking.c

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,24 @@ void setDeferredAggregateLen(client *c, void *node, long length, char prefix) {
714714
* we return NULL in addReplyDeferredLen() */
715715
if (node == NULL) return;
716716

717+
/* Things like *2\r\n, %3\r\n or ~4\r\n are emitted very often by the protocol
718+
* so we have a few shared objects to use if the integer is small
719+
* like it is most of the times. */
720+
const size_t hdr_len = OBJ_SHARED_HDR_STRLEN(length);
721+
const int opt_hdr = length < OBJ_SHARED_BULKHDR_LEN;
722+
if (prefix == '*' && opt_hdr) {
723+
setDeferredReply(c, node, shared.mbulkhdr[length]->ptr, hdr_len);
724+
return;
725+
}
726+
if (prefix == '%' && opt_hdr) {
727+
setDeferredReply(c, node, shared.maphdr[length]->ptr, hdr_len);
728+
return;
729+
}
730+
if (prefix == '~' && opt_hdr) {
731+
setDeferredReply(c, node, shared.sethdr[length]->ptr, hdr_len);
732+
return;
733+
}
734+
717735
char lenstr[128];
718736
size_t lenstr_len = sprintf(lenstr, "%c%ld\r\n", prefix, length);
719737
setDeferredReply(c, node, lenstr, lenstr_len);
@@ -806,12 +824,19 @@ void addReplyLongLongWithPrefix(client *c, long long ll, char prefix) {
806824
/* Things like $3\r\n or *2\r\n are emitted very often by the protocol
807825
* so we have a few shared objects to use if the integer is small
808826
* like it is most of the times. */
809-
if (prefix == '*' && ll < OBJ_SHARED_BULKHDR_LEN && ll >= 0) {
827+
const int opt_hdr = ll < OBJ_SHARED_BULKHDR_LEN && ll >= 0;
828+
if (prefix == '*' && opt_hdr) {
810829
addReply(c,shared.mbulkhdr[ll]);
811830
return;
812-
} else if (prefix == '$' && ll < OBJ_SHARED_BULKHDR_LEN && ll >= 0) {
831+
} else if (prefix == '$' && opt_hdr) {
813832
addReply(c,shared.bulkhdr[ll]);
814833
return;
834+
} else if (prefix == '%' && opt_hdr) {
835+
addReply(c,shared.maphdr[ll]);
836+
return;
837+
} else if (prefix == '~' && opt_hdr) {
838+
addReply(c,shared.sethdr[ll]);
839+
return;
815840
}
816841

817842
buf[0] = prefix;

src/server.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1790,6 +1790,10 @@ void createSharedObjects(void) {
17901790
sdscatprintf(sdsempty(),"*%d\r\n",j));
17911791
shared.bulkhdr[j] = createObject(OBJ_STRING,
17921792
sdscatprintf(sdsempty(),"$%d\r\n",j));
1793+
shared.maphdr[j] = createObject(OBJ_STRING,
1794+
sdscatprintf(sdsempty(),"%%%d\r\n",j));
1795+
shared.sethdr[j] = createObject(OBJ_STRING,
1796+
sdscatprintf(sdsempty(),"~%d\r\n",j));
17931797
}
17941798
/* The following two shared objects, minstring and maxstring, are not
17951799
* actually used for their value but as a special object meaning

src/server.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ typedef long long ustime_t; /* microsecond time type. */
109109
#define PROTO_SHARED_SELECT_CMDS 10
110110
#define OBJ_SHARED_INTEGERS 10000
111111
#define OBJ_SHARED_BULKHDR_LEN 32
112+
#define OBJ_SHARED_HDR_STRLEN(_len_) (((_len_) < 10) ? 4 : 5) /* see shared.mbulkhdr etc. */
112113
#define LOG_MAX_LEN 1024 /* Default maximum length of syslog messages.*/
113114
#define AOF_REWRITE_ITEMS_PER_CMD 64
114115
#define AOF_ANNOTATION_LINE_MAX_LEN 1024
@@ -1229,7 +1230,9 @@ struct sharedObjectsStruct {
12291230
*select[PROTO_SHARED_SELECT_CMDS],
12301231
*integers[OBJ_SHARED_INTEGERS],
12311232
*mbulkhdr[OBJ_SHARED_BULKHDR_LEN], /* "*<value>\r\n" */
1232-
*bulkhdr[OBJ_SHARED_BULKHDR_LEN]; /* "$<value>\r\n" */
1233+
*bulkhdr[OBJ_SHARED_BULKHDR_LEN], /* "$<value>\r\n" */
1234+
*maphdr[OBJ_SHARED_BULKHDR_LEN], /* "%<value>\r\n" */
1235+
*sethdr[OBJ_SHARED_BULKHDR_LEN]; /* "~<value>\r\n" */
12331236
sds minstring, maxstring;
12341237
};
12351238

0 commit comments

Comments
 (0)