summaryrefslogtreecommitdiff
path: root/src/t_hash.c
diff options
context:
space:
mode:
authorMadelyn Olson <34459052+madolson@users.noreply.github.com>2023-05-08 16:11:20 -0700
committerGitHub <noreply@github.com>2023-05-08 16:11:20 -0700
commita129a601818d88a2f2aa9d954afc8afa43030f7e (patch)
tree85de9f99c4cb77621a14ef97c3f21439aba5fb20 /src/t_hash.c
parent51af17e3cf62cf77258c35509544a9b273327d2a (diff)
downloadredis-a129a601818d88a2f2aa9d954afc8afa43030f7e.tar.gz
Minor performance improvement to SADD and HSET (#12019)
For sets and hashes that will eventually be stored as the hash encoding, it's much faster to immediately convert them to their hash encoding and then perform the insertions since it avoids the O(N) search and frequent reallocations. This change checks the number of arguments in the incoming command, and converts the data-structure if the number of new entries exceeds the listpack-max-entries configuration. This can cause us to over-allocate memory if their are duplicate entries in the input, which is unexpected. unstable Summary: throughput summary: 805.54 requests per second latency summary (msec): avg min p50 p95 p99 max 61.908 25.680 68.351 73.279 75.967 79.295 hset-improvement Summary: throughput summary: 4701.46 requests per second latency summary (msec): avg min p50 p95 p99 max 10.546 0.832 11.959 12.471 13.119 14.967
Diffstat (limited to 'src/t_hash.c')
-rw-r--r--src/t_hash.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/t_hash.c b/src/t_hash.c
index 6005f4442..f7d5af649 100644
--- a/src/t_hash.c
+++ b/src/t_hash.c
@@ -43,6 +43,16 @@ void hashTypeTryConversion(robj *o, robj **argv, int start, int end) {
if (o->encoding != OBJ_ENCODING_LISTPACK) return;
+ /* We guess that most of the values in the input are unique, so
+ * if there are enough arguments we create a pre-sized hash, which
+ * might overallocate memory if their are duplicates. */
+ size_t new_fields = (end - start + 1) / 2;
+ if (new_fields > server.hash_max_listpack_entries) {
+ hashTypeConvert(o, OBJ_ENCODING_HT);
+ dictExpand(o->ptr, new_fields);
+ return;
+ }
+
for (i = start; i <= end; i++) {
if (!sdsEncodedObject(argv[i]))
continue;