Skip to content

Commit 6ebf338

Browse files
feat: add precision-summary field with clean QPS, P50, P95 metrics (#34)
* feat: add precision-summary field with clean QPS, P50, P95 metrics - Add precision-summary field alongside existing precision field - Contains simplified dict with just qps, p50, p95 for each precision level - P50/P95 values converted to milliseconds for consistency - QPS rounded to 1 decimal place for readability - Maintains backward compatibility with existing precision field - Enables easier parsing and analysis of performance metrics * Update README.md to include easy docker steps and how to check results fast. --------- Co-authored-by: fcostaoliveira <filipe@redis.com>
1 parent cbe4c83 commit 6ebf338

File tree

2 files changed

+103
-57
lines changed

2 files changed

+103
-57
lines changed

README.md

Lines changed: 78 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,84 @@ scenario against which it should be tested. A specific scenario may assume
1616
running the server in a single or distributed mode, a different client
1717
implementation and the number of client instances.
1818

19+
20+
## Quick Start
21+
22+
### Quick Start with Docker
23+
24+
The easiest way to run vector-db-benchmark is using Docker. We provide pre-built images on Docker Hub.
25+
26+
```bash
27+
# Pull the latest image
28+
docker pull filipe958/vector-db-benchmark:latest
29+
30+
# Run with help
31+
docker run --rm filipe958/vector-db-benchmark:latest run.py --help
32+
33+
# Check which datasets are available
34+
docker run --rm filipe958/vector-db-benchmark:latest run.py --describe datasets
35+
36+
# Basic Redis benchmark with local Redis
37+
docker run --rm -v $(pwd)/results:/app/results --network=host \
38+
filipe958/vector-db-benchmark:latest \
39+
run.py --host localhost --engines redis-default-simple --datasets glove-25-angular
40+
41+
# At the end of the run, you will find the results in the `results` directory. Lets open the summary one, in the precision summary
42+
43+
$ jq ".precision_summary" results/*-summary.json
44+
{
45+
"0.91": {
46+
"qps": 1924.5,
47+
"p50": 49.828,
48+
"p95": 58.427
49+
},
50+
"0.94": {
51+
"qps": 1819.9,
52+
"p50": 51.68,
53+
"p95": 66.83
54+
},
55+
"0.9775": {
56+
"qps": 1477.8,
57+
"p50": 65.368,
58+
"p95": 73.849
59+
},
60+
"0.9950": {
61+
"qps": 1019.8,
62+
"p50": 95.115,
63+
"p95": 106.73
64+
}
65+
}
66+
```
67+
68+
### Using with Redis
69+
70+
For testing with Redis, start a Redis container first:
71+
72+
```bash
73+
# Start Redis container
74+
docker run -d --name redis-test -p 6379:6379 redis:8.2-rc1-bookworm
75+
76+
# Run benchmark against Redis
77+
78+
docker run --rm -v $(pwd)/results:/app/results --network=host \
79+
filipe958/vector-db-benchmark:latest \
80+
run.py --host localhost --engines redis-default-simple --dataset random-100
81+
82+
# Or use the convenience script
83+
./docker-run.sh -H localhost -e redis-default-simple -d random-100
84+
85+
86+
# Clean up Redis container when done
87+
docker stop redis-test && docker rm redis-test
88+
```
89+
90+
### Available Docker Images
91+
92+
- **Latest**: `filipe958/vector-db-benchmark:latest`
93+
94+
For detailed Docker setup and publishing information, see [DOCKER_SETUP.md](DOCKER_SETUP.md).
95+
96+
1997
## Data sets
2098

2199
We have a number of precomputed data sets. All data sets have been pre-split into train/test and include ground truth data for the top-100 nearest neighbors.
@@ -71,59 +149,6 @@ We have a number of precomputed data sets. All data sets have been pre-split int
71149
| Random Match Keyword Small Vocab-256: Small vocabulary keyword matching (no filters) | 256 | 1,000,000 | 10,000 | 100 | Cosine |
72150

73151

74-
## 🐳 Docker Usage
75-
76-
The easiest way to run vector-db-benchmark is using Docker. We provide pre-built images on Docker Hub.
77-
78-
### Quick Start with Docker
79-
80-
```bash
81-
# Pull the latest image
82-
docker pull filipe958/vector-db-benchmark:latest
83-
84-
# Run with help
85-
docker run --rm filipe958/vector-db-benchmark:latest run.py --help
86-
87-
88-
# Basic Redis benchmark with local Redis (recommended)
89-
docker run --rm -v $(pwd)/results:/app/results --network=host \
90-
filipe958/vector-db-benchmark:latest \
91-
run.py --host localhost --engines redis-default-simple --dataset random-100
92-
93-
# Without results output
94-
docker run --rm --network=host filipe958/vector-db-benchmark:latest \
95-
run.py --host localhost --engines redis-default-simple --dataset random-100
96-
97-
```
98-
99-
### Using with Redis
100-
101-
For testing with Redis, start a Redis container first:
102-
103-
```bash
104-
# Start Redis container
105-
docker run -d --name redis-test -p 6379:6379 redis:8.2-rc1-bookworm
106-
107-
# Run benchmark against Redis
108-
109-
docker run --rm -v $(pwd)/results:/app/results --network=host \
110-
filipe958/vector-db-benchmark:latest \
111-
run.py --host localhost --engines redis-default-simple --dataset random-100
112-
113-
# Or use the convenience script
114-
./docker-run.sh -H localhost -e redis-default-simple -d random-100
115-
116-
117-
# Clean up Redis container when done
118-
docker stop redis-test && docker rm redis-test
119-
```
120-
121-
### Available Docker Images
122-
123-
- **Latest**: `filipe958/vector-db-benchmark:latest`
124-
125-
For detailed Docker setup and publishing information, see [DOCKER_SETUP.md](DOCKER_SETUP.md).
126-
127152
## How to run a benchmark?
128153

129154
Benchmarks are implemented in server-client mode, meaning that the server is

engine/base_client/client.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,16 @@ def format_precision_key(precision_value: float) -> str:
3434
return f"{rounded:.4f}"
3535

3636

37-
def analyze_precision_performance(search_results: Dict[str, Any]) -> Dict[str, Dict[str, Any]]:
38-
"""Analyze search results to find best RPS at each actual precision level achieved."""
37+
def analyze_precision_performance(search_results: Dict[str, Any]) -> tuple[Dict[str, Dict[str, Any]], Dict[str, Dict[str, float]]]:
38+
"""Analyze search results to find best RPS at each actual precision level achieved.
39+
40+
Returns:
41+
tuple: (precision_dict, precision_summary_dict)
42+
- precision_dict: Full precision analysis with config details
43+
- precision_summary_dict: Simplified summary with just QPS, P50, P95
44+
"""
3945
precision_dict = {}
46+
precision_summary_dict = {}
4047

4148
# First, collect all actual precision levels achieved by experiments and format them
4249
precision_mapping = {} # Maps formatted precision to actual precision
@@ -53,6 +60,8 @@ def analyze_precision_performance(search_results: Dict[str, Any]) -> Dict[str, D
5360
best_rps = 0
5461
best_config = None
5562
best_experiment_id = None
63+
best_p50_time = 0
64+
best_p95_time = 0
5665

5766
for experiment_id, experiment_data in search_results.items():
5867
mean_precision = experiment_data["results"]["mean_precisions"]
@@ -66,16 +75,26 @@ def analyze_precision_performance(search_results: Dict[str, Any]) -> Dict[str, D
6675
"search_params": experiment_data["params"]["search_params"]
6776
}
6877
best_experiment_id = experiment_id
78+
best_p50_time = experiment_data["results"]["p50_time"]
79+
best_p95_time = experiment_data["results"]["p95_time"]
6980

7081
# Add to precision dict with the formatted precision as key
7182
if best_config is not None:
83+
# Full precision analysis (existing format)
7284
precision_dict[formatted_precision] = {
7385
"rps": best_rps,
7486
"config": best_config,
7587
"experiment_id": best_experiment_id
7688
}
7789

78-
return precision_dict
90+
# Simplified precision summary
91+
precision_summary_dict[formatted_precision] = {
92+
"qps": round(best_rps, 1),
93+
"p50": round(best_p50_time * 1000, 3), # Convert to ms
94+
"p95": round(best_p95_time * 1000, 3) # Convert to ms
95+
}
96+
97+
return precision_dict, precision_summary_dict
7998

8099
warnings.filterwarnings("ignore", category=DeprecationWarning)
81100

@@ -285,10 +304,12 @@ def run_experiment(
285304

286305
# Add precision analysis if search results exist
287306
if results["search"]:
288-
precision_analysis = analyze_precision_performance(results["search"])
307+
precision_analysis, precision_summary = analyze_precision_performance(results["search"])
289308
if precision_analysis: # Only add if we have precision data
290309
results["precision"] = precision_analysis
310+
results["precision_summary"] = precision_summary
291311
print(f"Added precision analysis with {len(precision_analysis)} precision thresholds")
312+
print(f"Added precision summary with {len(precision_summary)} precision levels")
292313

293314
summary_file = f"{self.name}-{dataset.config.name}-summary.json"
294315
summary_path = RESULTS_DIR / summary_file

0 commit comments

Comments
 (0)