Skip to content

Commit 9bd4356

Browse files
committed
Add detailed benchmark docs and facet-heavy search benchmark
1 parent 4421383 commit 9bd4356

File tree

3 files changed

+57
-10
lines changed

3 files changed

+57
-10
lines changed

README.md

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -290,13 +290,5 @@ APIs:
290290

291291
Snapshots are optional; if you don’t provide them, itemsjs rebuilds indexes as before.
292292

293-
Benchmark (Node):
294-
- Run `npm run benchmark:snapshot` to compare fresh build vs snapshot load (defaults to 1k, 10k and 30k items). Override sizes with `SIZES=5000,20000 npm run benchmark:snapshot`.
295-
- Output includes cold-start speedup ratio (build/load). Note: real-world cost in browser also includes `fetch` + `JSON.parse` time if you download the snapshot.
296-
297-
Search benchmark (Node):
298-
- Run `npm run benchmark:search` to measure build/search/facets timings across scenarios (empty, query-only, filters-only, query+filters, boolean filter). Defaults to sizes 1k/10k/30k; override with `SIZES=5000,20000` and repeats with `REPEAT=10`.
299-
300-
Browser smoke test (manual/optional):
301-
- Build the bundle: `npm run build`.
302-
- EITHER open `benchmarks/browser-snapshot.html` directly in a browser, OR run `npm run serve:benchmark` and open `http://localhost:4173/` (auto-loads the snapshot page). It builds once, saves a snapshot to `localStorage`, and on refresh loads from it and logs a sample search.
293+
Benchmarks and browser smoke test:
294+
- See `docs/benchmarks.md` for snapshot/search benchmarks and the optional browser smoke test.

benchmarks/search.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ const sizes = process.env.SIZES
77
: defaultSizes;
88

99
const repeats = parseInt(process.env.REPEAT || '5', 10);
10+
const extraFacetsCount = parseInt(process.env.EXTRA_FACETS || '0', 10);
11+
const extraFacetValues = ['a', 'b', 'c'];
1012

1113
const tagsPool = Array.from({ length: 40 }, (_, i) => `tag${i}`);
1214
const actorsPool = Array.from({ length: 30 }, (_, i) => `actor${i}`);
@@ -28,10 +30,20 @@ function makeItems(count) {
2830
actors: [actor],
2931
category,
3032
popular,
33+
...makeExtraFacets(i),
3134
};
3235
});
3336
}
3437

38+
function makeExtraFacets(index) {
39+
const result = {};
40+
for (let j = 0; j < extraFacetsCount; j++) {
41+
const val = extraFacetValues[(index + j) % extraFacetValues.length];
42+
result[`facet_${j}`] = val;
43+
}
44+
return result;
45+
}
46+
3547
function average(arr) {
3648
if (!arr.length) return 0;
3749
return arr.reduce((a, b) => a + b, 0) / arr.length;
@@ -64,6 +76,15 @@ function runScenario(engine, input) {
6476

6577
function logResult(size, buildMs, results) {
6678
console.log(`items: ${size}`);
79+
console.log(
80+
` facets: tags(${tagsPool.length}), actors(${actorsPool.length}), category(${categories.length}), popular(boolean)`,
81+
);
82+
if (extraFacetsCount > 0) {
83+
console.log(` extra facets: ${extraFacetsCount} (3 values each)`);
84+
}
85+
console.log(
86+
' fields: name (boosted), tags, actors; each item has 3 tags, 1 actor, 1 category, boolean popular',
87+
);
6788
console.log(` build (ms): ${buildMs.toFixed(1)}`);
6889
Object.entries(results).forEach(([name, data]) => {
6990
console.log(
@@ -98,6 +119,12 @@ function main() {
98119
},
99120
};
100121

122+
if (extraFacetsCount > 0) {
123+
for (let i = 0; i < extraFacetsCount; i++) {
124+
config.aggregations[`facet_${i}`] = { title: `Facet ${i}` };
125+
}
126+
}
127+
101128
const buildStart = performance.now();
102129
const engine = itemsjs(data, config);
103130
const buildEnd = performance.now();

docs/benchmarks.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Benchmarks
2+
3+
This folder contains small, reproducible benchmarks for ItemsJS. They are optional and not part of the published package.
4+
5+
## Snapshot benchmark
6+
7+
Script: `npm run benchmark:snapshot`
8+
9+
- Compares fresh index build vs loading from snapshot.
10+
- Defaults: sizes `1000,10000,30000`. Override with `SIZES=5000,20000 npm run benchmark:snapshot`.
11+
- Output includes cold-start speedup (build/load) and snapshot size.
12+
- Note: In the browser, total cost also includes `fetch + JSON.parse` if you download the snapshot.
13+
14+
## Search benchmark
15+
16+
Script: `npm run benchmark:search`
17+
18+
- Measures build/search/facets timings across scenarios: empty, query-only, filters-only, query+filters, boolean filter.
19+
- Defaults: sizes `1000,10000,30000`, repeats per scenario `5`.
20+
- Override: `SIZES=5000,20000`, `REPEAT=10`.
21+
- Dataset per size: 40 tags, 30 actors, 4 categories, boolean `popular`; each item has 3 tags, 1 actor, 1 category. Facets: tags, actors, category, popular. Searchable fields: name (boosted), tags, actors.
22+
- Stress facet-heavy setups with `EXTRA_FACETS=1000` (each with 3 values) to see scaling for many facets.
23+
24+
## Browser smoke test
25+
26+
- Build: `npm run build`.
27+
- Run: `npm run serve:benchmark` and open `http://localhost:4173/` (serves `benchmarks/browser-snapshot.html`), or open the HTML directly.
28+
- First load builds and stores a snapshot in `localStorage`; subsequent loads use the snapshot and log a sample search. Green message = OK; red/error or stuck on “Loading…” → check console.

0 commit comments

Comments
 (0)