Skip to content

Instantly share code, notes, and snippets.

@fiatjaf
Created December 13, 2022 14:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fiatjaf/84058d5846bb042d376a63525bc8f834 to your computer and use it in GitHub Desktop.
Save fiatjaf/84058d5846bb042d376a63525bc8f834 to your computer and use it in GitHub Desktop.
fetching a list of data from Redis with ZRANGE + GET benchmarks using 4 different methods
package main
import (
"context"
"crypto/sha256"
"encoding/hex"
"log"
"net/url"
"strconv"
"testing"
"github.com/go-redis/redis/v8"
)
func BenchmarkRedisScript(b *testing.B) {
var rds *redis.Client
if rurl, err := url.Parse("redis://127.0.0.1:6379"); err != nil {
log.Fatal(err)
return
} else {
pw, _ := rurl.User.Password()
rds = redis.NewClient(&redis.Options{
Addr: rurl.Host,
Password: pw,
})
if err := rds.Ping(context.Background()).Err(); err != nil {
log.Fatal(err)
return
}
}
ctx := context.Background()
// add values
for i := 0; i < 100; i++ {
idh := sha256.Sum256([]byte{byte(i)})
id := hex.EncodeToString(idh[:])
rds.ZAdd(ctx, "test", &redis.Z{
Score: 99.9 - float64(i),
Member: id,
})
rds.Set(ctx, id, "nada "+strconv.Itoa(i), 0)
}
// setup script
script1 := redis.NewScript(`
local ids = redis.call('ZREVRANGEBYSCORE', KEYS[1], 999999999999999, 0, 'LIMIT', 0, 100)
local data = {}
for i, v in ipairs(ids) do
data[i] = redis.call("GET", v)
end
return data
`)
script1.Load(ctx, rds)
script2 := redis.NewScript(`
local ids = redis.call('ZREVRANGEBYSCORE', KEYS[1], 999999999999999, 0, 'LIMIT', 0, 100)
return redis.call('MGET', unpack(ids))
`)
script2.Load(ctx, rds)
b.Run("load values manually", func(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
data := make([]string, 100)
if ids, err := rds.ZRevRangeByScore(ctx, "test", &redis.ZRangeBy{
Min: "0",
Max: "999999999999999",
Count: int64(100),
Offset: 0,
}).Result(); err == nil {
for i, id := range ids {
d, err := rds.Get(ctx, id).Result()
if err != nil {
continue
}
data[i] = d
}
} else {
b.Error(err)
}
if data[4] != "nada 4" || data[77] != "nada 77" {
b.Error("wrong data")
}
}
})
b.Run("load values with mget", func(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
data := make([]string, 100)
if ids, err := rds.ZRevRangeByScore(ctx, "test", &redis.ZRangeBy{
Min: "0",
Max: "999999999999999",
Count: int64(100),
Offset: 0,
}).Result(); err == nil {
if items, err := rds.MGet(ctx, ids...).Result(); err == nil {
for i, d := range items {
data[i] = d.(string)
}
}
} else {
b.Error(err)
}
if data[27] != "nada 27" || data[74] != "nada 74" {
b.Error("wrong data")
}
}
})
b.Run("load values with a manual script", func(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
data := make([]string, 100)
if res, err := script1.EvalSha(ctx, rds, []string{"test"}).Result(); err == nil {
items := res.([]interface{})
for i, d := range items {
data[i] = d.(string)
}
} else {
b.Error(err)
}
if data[33] != "nada 33" || data[63] != "nada 63" {
b.Error("wrong data")
}
}
})
b.Run("load values with a mget script", func(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
data := make([]string, 100)
if res, err := script2.EvalSha(ctx, rds, []string{"test"}).Result(); err == nil {
items := res.([]interface{})
for i, d := range items {
data[i] = d.(string)
}
} else {
b.Error(err)
}
if data[1] != "nada 1" || data[99] != "nada 99" {
b.Errorf("wrong data")
}
}
})
}
fiatjaf@hazlitt ~/c/misc> go test -bench . 11:47
goos: linux
goarch: amd64
pkg: github.com/fiatjaf/misc
cpu: AMD Ryzen 3 3200G with Radeon Vega Graphics
BenchmarkRedisScript/load_values_manually-4 572 2834916 ns/op
BenchmarkRedisScript/load_values_with_mget-4 5042 241917 ns/op
BenchmarkRedisScript/load_values_with_a_manual_script-4 5372 199011 ns/op
BenchmarkRedisScript/load_values_with_a_mget_script-4 9078 133222 ns/op
PASS
ok github.com/fiatjaf/misc 5.420s
goos: linux
goarch: amd64
pkg: github.com/fiatjaf/misc
cpu: AMD Ryzen 3 3200G with Radeon Vega Graphics
BenchmarkRedisScript/load_values_manually-4 697 2905380 ns/op
BenchmarkRedisScript/load_values_with_mget-4 4996 203599 ns/op
BenchmarkRedisScript/load_values_with_a_manual_script-4 7395 184711 ns/op
BenchmarkRedisScript/load_values_with_a_mget_script-4 9392 148022 ns/op
PASS
ok github.com/fiatjaf/misc 6.046s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment