Motivation: during a discussion with a Redis user about using bitmaps for keeping track over periods, the user noted that setting ranges with multiple calls to SETBIT
can become expensive. The script is the result of that discussion.
An example of using the script from command line with "debug" mode:
$ export SHA1=`redis-cli SCRIPT LOAD "$(cat setbitrange.lua)"`
$ redis-cli EVALSHA $SHA1 1 foo 3 12 1
"00011111 11111000 "
$ redis-cli EVALSHA $SHA1 1 foo 6 9 0
"00011100 00111000 "
On a MacBook Pro (2015), a naive benchmark gives:
$ redis-benchmark -r 100000 -e EVALSHA $SHA1 1 __rand_int__ 3 55 1
====== EVALSHA 296d7f17353cc288e71ba28e1959506e6d924890 1 __rand_int__ 3 55 1 ======
100000 requests completed in 2.04 seconds
50 parallel clients
3 bytes payload
keep alive: 1
72.82% <= 1 milliseconds
100.00% <= 2 milliseconds
100.00% <= 2 milliseconds
49091.80 requests per second
Some thoughts:
- The dangling bits can probably be better (more optimally) handled with a couple of bitwise operations on the current byte they're at instead of calling (up to 2*7 = 14) SETBITs
- It would be interesting to see if BITFIELD can be used to further optimize this, probably not though ;P
- It would be even better to have this capability in Redis core API instead of relying on scripting or devloping a module (redis/redis#4553)