From 9c1a8d254ba286be235f137ad034a60334cbd0d4 Mon Sep 17 00:00:00 2001 From: filipe oliveira Date: Fri, 9 Dec 2022 10:06:25 +0000 Subject: [PATCH] Reduce rewriteClientCommandVector usage on EXPIRE command (#11602) There is overhead on Redis 7.0 EXPIRE command that is not present on 6.2.7. We could see that on the unstable profile there are around 7% of CPU cycles spent on rewriteClientCommandVector that are not present on 6.2.7. This was introduced in #8474. This PR reduces the overhead by using 2X rewriteClientCommandArgument instead of rewriteClientCommandVector. In this scenario rewriteClientCommandVector creates 4 arguments. the above usage of rewriteClientCommandArgument reduces the overhead in half. This PR should also improve PEXPIREAT performance by avoiding at all rewriteClientCommandArgument usage. Co-authored-by: Oran Agra (cherry picked from commit c3fb48da8b76ee143d1c380ccf9899752607c5d5) --- src/expire.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/expire.c b/src/expire.c index a6a40450e0dd0..eff55208bda1b 100644 --- a/src/expire.c +++ b/src/expire.c @@ -651,10 +651,19 @@ void expireGenericCommand(client *c, long long basetime, int unit) { } else { setExpire(c,c->db,key,when); addReply(c,shared.cone); - /* Propagate as PEXPIREAT millisecond-timestamp */ - robj *when_obj = createStringObjectFromLongLong(when); - rewriteClientCommandVector(c, 3, shared.pexpireat, key, when_obj); - decrRefCount(when_obj); + /* Propagate as PEXPIREAT millisecond-timestamp + * Only rewrite the command arg if not already PEXPIREAT */ + if (c->cmd->proc != pexpireatCommand) { + rewriteClientCommandArgument(c,0,shared.pexpireat); + } + + /* Avoid creating a string object when it's the same as argv[2] parameter */ + if (basetime != 0 || unit == UNIT_SECONDS) { + robj *when_obj = createStringObjectFromLongLong(when); + rewriteClientCommandArgument(c,2,when_obj); + decrRefCount(when_obj); + } + signalModifiedKey(c,c->db,key); notifyKeyspaceEvent(NOTIFY_GENERIC,"expire",key,c->db->id); server.dirty++;