[BUG] Performance degradation of HMSET command after upgrading to 7.4.2
Describe the bug
Upgrading the redis-server from 7.2.7 to 7.4.2, there are about 5% performance degradation of HMSET command. It seems that commit a25b153 was the chief culprit for this performance degradation.
To reproduce
I use the redis-benchmark and following command to test the performance before and after commit a25b153:
redis-benchmark -n 1000000 --csv HMSET test_HMSET username alice age 30 location Paris HGET_HASH_FIELD1 weugfuwebgfiwebviu HGET_HASH_FIELD2 ewuvbgevhberihvneirn HGET_HASH_FIELD3 weufgewihiwer HGET_HASH_FIELD4 4tvnreiknveir HGET_HASH_FIELD5 23rgwnrighnkwn2 HGET_HASH_FIELD6 23jrb234jbg34ibgi3
To avoid the influence of accidental factors, I conducted 15 rounds of testing, their @avg_latency_ms are as following:
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | average | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| after a25b153 | 0.176 | 0.185 | 0.182 | 0.188 | 0.19 | 0.185 | 0.201 | 0.21 | 0.187 | 0.178 | 0.191 | 0.194 | 0.201 | 0.172 | 0.178 | 0.18786667 |
| before a25b153 | 0.166 | 0.171 | 0.167 | 0.172 | 0.165 | 0.167 | 0.178 | 0.178 | 0.177 | 0.22 | 0.177 | 0.164 | 0.17 | 0.212 | 0.168 | 0.1768 |
I suspect the reason might be that this commit extracted the logic of lpFindCmp, which caused local variables that were previously directly accessible to be read from memory via arg-> now. Since HMSet command frequently calls lpFindCmp, this amplified the performance overhead.
Although the lpFindCmp function has inline keyword, I checked the assembly generated by objdump, it seems that GCC did not actually inline it.
Expected behavior
HMSET command has the same performance as before.
Additional information
I also performed instrumentation on the processCommand function in redis-server. I measured its execution time using clock_gettime, and the average execution time of the processCommand before and after a25b153 is 4.91us and 4.59us, respectively.
Source: redis/redis