summaryrefslogtreecommitdiff
path: root/src/networking.c
diff options
context:
space:
mode:
authorfilipe oliveira <filipecosta.90@gmail.com>2023-02-06 16:26:40 +0000
committerGitHub <noreply@github.com>2023-02-06 18:26:40 +0200
commitf3c6f9c2f44a7baf14de0f98b2b89c5c6c2781ba (patch)
tree4f216f9f177aeb53827680dcf5c7894fe04a1fc4 /src/networking.c
parent03347d04487daa5ee173f4d902351ee6a13618be (diff)
downloadredis-f3c6f9c2f44a7baf14de0f98b2b89c5c6c2781ba.tar.gz
Optimize ZRANGE replies WITHSCORES in case of integer scores (#11779)
If we have integer scores on the sorted set we're not using the fastest way to reply by calling `d2string` which uses `double2ll` and `ll2string` when it can, instead of `fpconv_dtoa`. This results by some 50% performance improvement in certain cases of integer scores for both RESP2 and RESP3, and no apparent impact on double scores. Co-authored-by: Oran Agra <oran@redislabs.com>
Diffstat (limited to 'src/networking.c')
-rw-r--r--src/networking.c75
1 files changed, 27 insertions, 48 deletions
diff --git a/src/networking.c b/src/networking.c
index 9eb557812..8f802532d 100644
--- a/src/networking.c
+++ b/src/networking.c
@@ -835,57 +835,36 @@ void setDeferredPushLen(client *c, void *node, long length) {
/* Add a double as a bulk reply */
void addReplyDouble(client *c, double d) {
- if (isinf(d)) {
- /* Libc in odd systems (Hi Solaris!) will format infinite in a
- * different way, so better to handle it in an explicit way. */
- if (c->resp == 2) {
- addReplyBulkCString(c, d > 0 ? "inf" : "-inf");
- } else {
- addReplyProto(c, d > 0 ? ",inf\r\n" : ",-inf\r\n",
- d > 0 ? 6 : 7);
- }
- } else if (isnan(d)) {
- /* Libc in some systems will format nan in a different way,
- * like nan, -nan, NAN, nan(char-sequence).
- * So we normalize it and create a single nan form in an explicit way. */
- if (c->resp == 2) {
- addReplyBulkCString(c, "nan");
- } else {
- addReplyProto(c, ",nan\r\n", 6);
- }
+ if (c->resp == 3) {
+ char dbuf[MAX_D2STRING_CHARS+3];
+ dbuf[0] = ',';
+ const int dlen = d2string(dbuf+1,sizeof(dbuf)-1,d);
+ dbuf[dlen+1] = '\r';
+ dbuf[dlen+2] = '\n';
+ dbuf[dlen+3] = '\0';
+ addReplyProto(c,dbuf,dlen+3);
} else {
char dbuf[MAX_LONG_DOUBLE_CHARS+32];
- int dlen = 0;
- if (c->resp == 2) {
- /* In order to prepend the string length before the formatted number,
- * but still avoid an extra memcpy of the whole number, we reserve space
- * for maximum header `$0000\r\n`, print double, add the resp header in
- * front of it, and then send the buffer with the right `start` offset. */
- dlen = fpconv_dtoa(d, dbuf+7);
- int digits = digits10(dlen);
- int start = 4 - digits;
- dbuf[start] = '$';
-
- /* Convert `dlen` to string, putting it's digits after '$' and before the
- * formatted double string. */
- for(int i = digits, val = dlen; val && i > 0 ; --i, val /= 10) {
- dbuf[start + i] = "0123456789"[val % 10];
- }
-
- dbuf[5] = '\r';
- dbuf[6] = '\n';
- dbuf[dlen+7] = '\r';
- dbuf[dlen+8] = '\n';
- dbuf[dlen+9] = '\0';
- addReplyProto(c,dbuf+start,dlen+9-start);
- } else {
- dbuf[0] = ',';
- dlen = fpconv_dtoa(d, dbuf+1);
- dbuf[dlen+1] = '\r';
- dbuf[dlen+2] = '\n';
- dbuf[dlen+3] = '\0';
- addReplyProto(c,dbuf,dlen+3);
+ /* In order to prepend the string length before the formatted number,
+ * but still avoid an extra memcpy of the whole number, we reserve space
+ * for maximum header `$0000\r\n`, print double, add the resp header in
+ * front of it, and then send the buffer with the right `start` offset. */
+ const int dlen = d2string(dbuf+7,sizeof(dbuf)-7,d);
+ int digits = digits10(dlen);
+ int start = 4 - digits;
+ dbuf[start] = '$';
+
+ /* Convert `dlen` to string, putting it's digits after '$' and before the
+ * formatted double string. */
+ for(int i = digits, val = dlen; val && i > 0 ; --i, val /= 10) {
+ dbuf[start + i] = "0123456789"[val % 10];
}
+ dbuf[5] = '\r';
+ dbuf[6] = '\n';
+ dbuf[dlen+7] = '\r';
+ dbuf[dlen+8] = '\n';
+ dbuf[dlen+9] = '\0';
+ addReplyProto(c,dbuf+start,dlen+9-start);
}
}