Skip to content

Commit 316aeb7

Browse files
committed
add concurrent test
1 parent 4a30663 commit 316aeb7

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed

hset_benchmark_test.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package redis_test
33
import (
44
"context"
55
"fmt"
6+
"sync"
67
"testing"
78
"time"
89

@@ -104,6 +105,61 @@ func benchmarkHSETOperations(b *testing.B, rdb *redis.Client, ctx context.Contex
104105
b.ReportMetric(float64(avgTimePerOpMs), "ms")
105106
}
106107

108+
// benchmarkHSETOperationsConcurrent performs the actual HSET benchmark for a given scale
109+
func benchmarkHSETOperationsConcurrent(b *testing.B, rdb *redis.Client, ctx context.Context, operations int) {
110+
hashKey := fmt.Sprintf("benchmark_hash_%d", operations)
111+
112+
b.ResetTimer()
113+
b.StartTimer()
114+
totalTimes := []time.Duration{}
115+
116+
for i := 0; i < b.N; i++ {
117+
b.StopTimer()
118+
// Clean up the hash before each iteration
119+
rdb.Del(ctx, hashKey)
120+
b.StartTimer()
121+
122+
startTime := time.Now()
123+
// Perform the specified number of HSET operations
124+
125+
wg := sync.WaitGroup{}
126+
wg.Add(operations)
127+
timesCh := make(chan time.Duration, operations)
128+
for j := 0; j < operations; j++ {
129+
go func(j int) {
130+
defer wg.Done()
131+
field := fmt.Sprintf("field_%d", j)
132+
value := fmt.Sprintf("value_%d", j)
133+
134+
err := rdb.HSet(ctx, hashKey, field, value).Err()
135+
if err != nil {
136+
b.Fatalf("HSET operation failed: %v", err)
137+
}
138+
timesCh <- time.Since(startTime))
139+
}(j)
140+
wg.Wait()
141+
close(timesCh)
142+
for d := range timesCh {
143+
totalTimes = append(totalTimes, d)
144+
}
145+
}
146+
}
147+
148+
// Stop the timer to calculate metrics
149+
b.StopTimer()
150+
151+
// Report operations per second
152+
opsPerSec := float64(operations*b.N) / b.Elapsed().Seconds()
153+
b.ReportMetric(opsPerSec, "ops/sec")
154+
155+
// Report average time per operation
156+
avgTimePerOp := b.Elapsed().Nanoseconds() / int64(operations*b.N)
157+
b.ReportMetric(float64(avgTimePerOp), "ns/op")
158+
// report average time in milliseconds from totalTimes
159+
avgTimePerOpMs := totalTimes[0].Milliseconds() / int64(len(totalTimes))
160+
b.ReportMetric(float64(avgTimePerOpMs), "ms")
161+
}
162+
107163
// BenchmarkHSETPipelined benchmarks HSET operations using pipelining for better performance
108164
func BenchmarkHSETPipelined(b *testing.B) {
109165
ctx := context.Background()
@@ -134,6 +190,36 @@ func BenchmarkHSETPipelined(b *testing.B) {
134190
}
135191
}
136192

193+
func BenchmarkHSET_Concurrent(b *testing.B) {
194+
ctx := context.Background()
195+
196+
// Setup Redis client
197+
rdb := redis.NewClient(&redis.Options{
198+
Addr: "localhost:6379",
199+
DB: 0,
200+
PoolSize: 1000,
201+
})
202+
defer rdb.Close()
203+
204+
// Test connection
205+
if err := rdb.Ping(ctx).Err(); err != nil {
206+
b.Skipf("Redis server not available: %v", err)
207+
}
208+
209+
// Clean up before and after tests
210+
defer func() {
211+
rdb.FlushDB(ctx)
212+
}()
213+
214+
scales := []int{1, 10, 100, 1000, 10000, 100000}
215+
216+
for _, scale := range scales {
217+
b.Run(fmt.Sprintf("HSET_%d_operations_concurrent", scale), func(b *testing.B) {
218+
benchmarkHSETOperationsConcurrent(b, rdb, ctx, scale)
219+
})
220+
}
221+
}
222+
137223
// benchmarkHSETPipelined performs HSET benchmark using pipelining
138224
func benchmarkHSETPipelined(b *testing.B, rdb *redis.Client, ctx context.Context, operations int) {
139225
hashKey := fmt.Sprintf("benchmark_hash_pipelined_%d", operations)

0 commit comments

Comments
 (0)