Skip to content

Instantly share code, notes, and snippets.

@m3ngyang
Last active October 7, 2022 11:02
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 m3ngyang/a10077966a548a2b7742e8553110ab58 to your computer and use it in GitHub Desktop.
Save m3ngyang/a10077966a548a2b7742e8553110ab58 to your computer and use it in GitHub Desktop.
Redisearch KNN benchmark
package main
import (
"context"
"encoding/binary"
"fmt"
"math"
"math/rand"
"testing"
"time"
"github.com/RediSearch/redisearch-go/redisearch"
"github.com/rueian/rueidis"
)
var INDEXNAME = "redisearch_benchmark"
var HOSTNAME = "127.0.0.1:6379"
func float32ToBytes(floats []float32) []byte {
result := make([]byte, 0)
for _, float := range floats {
bytes := make([]byte, 4)
bits := math.Float32bits(float)
binary.LittleEndian.PutUint32(bytes, bits)
result = append(result, bytes...)
}
return result
}
func BenchmarkByName(b *testing.B) {
rand.Seed(time.Now().UnixNano())
client, err := rueidis.NewClient(rueidis.ClientOption{InitAddress: []string{HOSTNAME}})
if err != nil {
panic(err)
}
// FT.CREATE redisearch_benchmark ON HASH PREFIX 1 movie: SCHEMA title TEXT year NUMERIC v VECTOR FLAT 6 TYPE FLOAT32 DIM 4 DISTANCE_METRIC L2
ctx := context.Background()
if err := client.Do(ctx, client.B().Arbitrary("FT.CREATE", INDEXNAME, "ON", "HASH", "PREFIX", "1", "movie:", "SCHEMA").
Args("title", "TEXT").
Args("year", "NUMERIC").
Args("v", "VECTOR", "HNSW", "6", "TYPE", "FLOAT32", "DIM", "4", "DISTANCE_METRIC", "L2").Build()).Error(); err != nil {
panic(err)
}
sampleNum := int(1e5)
id := 0
for id < sampleNum {
now := time.Now().UnixNano()
key := fmt.Sprintf("movie:matrix_%d", now)
vec := float32ToBytes([]float32{rand.Float32(), rand.Float32(), rand.Float32(), rand.Float32()})
title := fmt.Sprintf("Matrix%d", now)
year := rand.Intn(100) + 1850
if err := client.Do(ctx, client.B().Hset().Key(key).FieldValue().
FieldValue("title", title).
FieldValue("year", fmt.Sprintf("%d", year)).
FieldValue("v", string(vec)).Build()).Error(); err != nil {
panic(err)
}
id++
}
b.Run("rueidis", func(b *testing.B) {
if err != nil {
panic(err)
}
ctx := context.Background()
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
vec := float32ToBytes([]float32{rand.Float32(), rand.Float32(), rand.Float32(), rand.Float32()})
_, err := client.Do(ctx, client.B().FtSearch().Index(INDEXNAME).
Query("(@year:[1900 2000])=>[KNN 100 @v $B]").Sortby("__v_score").Asc().
Limit().OffsetNum(0, 100).Params().Nargs(2).
NameValue().NameValue("B", string(vec)).Dialect(2).Build()).ToArray()
if err != nil {
b.Fatal(err)
}
}
})
b.StopTimer()
})
b.Run("redigo", func(b *testing.B) {
c := redisearch.NewClient(HOSTNAME, INDEXNAME)
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
vec := float32ToBytes([]float32{rand.Float32(), rand.Float32(), rand.Float32(), rand.Float32()})
q := redisearch.NewQuery("(@year:[1900 2000])=>[KNN 100 @v $B]").SetSortBy("__v_score", true).
Limit(0, 100).SetParams(map[string]interface{}{"B": vec}).SetDialect(2)
_, _, err := c.Search(q)
if err != nil {
b.Fatal(err)
}
}
})
b.StopTimer()
})
client.Close()
fmt.Println("DONE")
}
@m3ngyang
Copy link
Author

m3ngyang commented Oct 7, 2022

KNN Benchmark for official redisearch go client and rueidis client.

redisearch config.

# THREADED I/O
io-threads 4
io-threads-do-reads yes

run command

docker run -p 6379:6379 -d --name test-redisearch \
    -v redis.conf:/etc/redis/redis.conf \
    redislabs/redisearch:2.4.12

test result:
image

Seems no significant improvement for FT.SEARCH when using the auto pipeline.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment