From 9d336ac398d3a28f6e5e76f1b3b110bab949bcc5 Mon Sep 17 00:00:00 2001 From: uriyage <78144248+uriyage@users.noreply.github.com> Date: Tue, 28 Feb 2023 19:38:58 +0200 Subject: Try to trim strings only when applicable (#11817) As `sdsRemoveFreeSpace` have an impact on performance even if it is a no-op (see details at #11508). Only call the function when there is a possibility that the string contains free space. * For strings coming from the network, it's only if they're bigger than PROTO_MBULK_BIG_ARG * For strings coming from scripts, it's only if they're smaller than LUA_CMD_OBJCACHE_MAX_LEN * For strings coming from modules, it could be anything. Co-authored-by: Oran Agra Co-authored-by: sundb --- src/object.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) (limited to 'src/object.c') diff --git a/src/object.c b/src/object.c index f64695061..c89f5aa85 100644 --- a/src/object.c +++ b/src/object.c @@ -609,14 +609,20 @@ int isObjectRepresentableAsLongLong(robj *o, long long *llval) { } /* Optimize the SDS string inside the string object to require little space, - * in case there is more than 10% of free space at the end of the SDS - * string. This happens because SDS strings tend to overallocate to avoid - * wasting too much time in allocations when appending to the string. */ -void trimStringObjectIfNeeded(robj *o) { - if (o->encoding == OBJ_ENCODING_RAW && - sdsavail(o->ptr) > sdslen(o->ptr)/10) - { - o->ptr = sdsRemoveFreeSpace(o->ptr, 0); + * in case there is more than 10% of free space at the end of the SDS. */ +void trimStringObjectIfNeeded(robj *o, int trim_small_values) { + if (o->encoding != OBJ_ENCODING_RAW) return; + /* A string may have free space in the following cases: + * 1. When an arg len is greater than PROTO_MBULK_BIG_ARG the query buffer may be used directly as the SDS string. + * 2. When utilizing the argument caching mechanism in Lua. + * 3. When calling from RM_TrimStringAllocation (trim_small_values is true). */ + size_t len = sdslen(o->ptr); + if (len >= PROTO_MBULK_BIG_ARG || + trim_small_values|| + (server.executing_client && server.executing_client->flags & CLIENT_SCRIPT && len < LUA_CMD_OBJCACHE_MAX_LEN)) { + if (sdsavail(o->ptr) > len/10) { + o->ptr = sdsRemoveFreeSpace(o->ptr, 0); + } } } @@ -685,15 +691,8 @@ robj *tryObjectEncoding(robj *o) { } /* We can't encode the object... - * - * Do the last try, and at least optimize the SDS string inside - * the string object to require little space, in case there - * is more than 10% of free space at the end of the SDS string. - * - * We do that only for relatively large strings as this branch - * is only entered if the length of the string is greater than - * OBJ_ENCODING_EMBSTR_SIZE_LIMIT. */ - trimStringObjectIfNeeded(o); + * Do the last try, and at least optimize the SDS string inside */ + trimStringObjectIfNeeded(o, 0); /* Return the original object. */ return o; -- cgit v1.2.1