Last active
October 7, 2022 11:02
-
-
Save m3ngyang/a10077966a548a2b7742e8553110ab58 to your computer and use it in GitHub Desktop.
Redisearch KNN benchmark
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
KNN Benchmark for official redisearch go client and rueidis client.
redisearch config.
run command
test result:

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