iterable-linq-utility 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -12
- package/dist/index.d.cts +457 -1
- package/dist/index.d.ts +457 -1
- package/dist/iterable-linq-utility.js +584 -253
- package/dist/iterable-linq-utility.umd.cjs +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -59,6 +59,26 @@ pnpm bench chains # only the chains
|
|
|
59
59
|
BENCH_TIME=1000 pnpm bench # more time for each case (default 500 ms): more samples, less noise
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
+
### Report
|
|
63
|
+
|
|
64
|
+
A pull request that adds an operation or changes its performance pastes the report in its description, as it is:
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
pnpm bench:report functions/sum # the same filter as pnpm bench
|
|
68
|
+
BENCH_HOST="MacBook Pro M3" pnpm bench:report functions/sum # names the host, which a container cannot see
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
```text
|
|
72
|
+
Environment: Alpine Linux v3.24 (Docker), arm64, 12 cores, CPU unknown · host MacBook Pro M3 · Node v24.20.0 · Vitest 5.0.2 · BENCH_TIME 500 ms · commit 2fba44d
|
|
73
|
+
|
|
74
|
+
| case | variant | ops/s | mean (ms) | p75 (ms) | p99 (ms) | rme | vs native |
|
|
75
|
+
| --- | --- | --- | --- | --- | --- | --- | --- |
|
|
76
|
+
| sum/map | native | 567 | 1.79 | 1.76 | 3.64 | ±2.5% | — |
|
|
77
|
+
| sum/map | chain | 855 | 1.2 | 1.26 | 1.76 | ±1.8% | +51% |
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
`vs native` compares the ops/s with the `native` case of the same group. When a baseline exists, a `vs baseline` column compares them with it. [ADR 0021](docs/decisions/0021-benchmark-standards.md) explains the format.
|
|
81
|
+
|
|
62
82
|
### Find regressions
|
|
63
83
|
|
|
64
84
|
A baseline is a saved run. Each table shows it as extra rows, marked `(baseline)`, next to the new run.
|
|
@@ -68,6 +88,7 @@ git switch main
|
|
|
68
88
|
pnpm bench:baseline # saves every result in .bench/
|
|
69
89
|
git switch my-branch
|
|
70
90
|
pnpm bench # shows each case next to its "(baseline)" row
|
|
91
|
+
pnpm bench:report functions/sum # or the report, with a "vs baseline" column
|
|
71
92
|
```
|
|
72
93
|
|
|
73
94
|
The timings depend on the machine, so `.bench/` is not committed and the benchmarks do not run in CI. Create the baseline and the new run on the same machine, with the same load.
|
|
@@ -76,7 +97,7 @@ The timings depend on the machine, so `.bench/` is not committed and the benchma
|
|
|
76
97
|
|
|
77
98
|
| Column | Meaning |
|
|
78
99
|
|---|---|
|
|
79
|
-
| `hz` | runs per second: higher is faster |
|
|
100
|
+
| `hz` | runs per second (ops/s in the report): higher is faster |
|
|
80
101
|
| `mean`, `p75`, `p99` | time of one run, in ms |
|
|
81
102
|
| `rme` | relative margin of error |
|
|
82
103
|
| `samples` | how many runs were measured |
|
|
@@ -85,26 +106,28 @@ A difference smaller than the `rme` of the two rows is noise.
|
|
|
85
106
|
|
|
86
107
|
### Add a benchmark
|
|
87
108
|
|
|
88
|
-
Create `test/bench/functions/<name>.bench.ts`
|
|
109
|
+
Create `test/bench/functions/<name>.bench.ts`. `scenarios()` registers the standard groups of [ADR 0021](docs/decisions/0021-benchmark-standards.md) and [ADR 0022](docs/decisions/0022-benchmark-scenarios-in-practice.md): `<name>/direct` on `numbers`, `<name>/small` on `small`, `<name>/map` and `<name>/filter` after `map(double)` and `filter(isEven)`. `group()` adds one more group on `numbers`: an early exit (`start`, `middle`) or an optional callback.
|
|
89
110
|
|
|
90
111
|
```ts
|
|
91
|
-
import { test } from 'vitest';
|
|
92
112
|
import * as Helpers from '../helpers';
|
|
93
113
|
|
|
94
114
|
import * as IterableLinq from 'iterable-linq-utility';
|
|
95
115
|
|
|
96
116
|
// Read the exports once: an imported binding goes through a module runner getter on every read.
|
|
97
|
-
const {
|
|
98
|
-
const {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
.run();
|
|
117
|
+
const { Functions } = IterableLinq;
|
|
118
|
+
const { double, scenarios, sum } = Helpers;
|
|
119
|
+
|
|
120
|
+
scenarios('map', {
|
|
121
|
+
native: values => sum(values.map(double)), // an array
|
|
122
|
+
chain: chain => sum(chain.map(double)), // a chain
|
|
123
|
+
Functions: values => sum(Functions.map(values, double)) // an iterable
|
|
105
124
|
});
|
|
106
125
|
```
|
|
107
126
|
|
|
127
|
+
- `native` is the array method a user would write. Add `loop`, a hand-written `for…of`, when the array method is a different algorithm (`reduce` for `sum`); when there is no array method, `native` is the loop.
|
|
128
|
+
- `pnpm check:structure` fails when the bench of an operation has no `direct` or `small` group. `test/bench/functions/sum.bench.ts` is the example.
|
|
129
|
+
- The benches of `test/bench/chains/<scenario>.bench.ts`, and the groups that need other data, use `cases(bench, '<function>/<group>')` directly: the id is also the baseline folder.
|
|
130
|
+
|
|
108
131
|
- Every table needs at least two cases: add a native reference.
|
|
109
132
|
- Import the library and the helpers as namespaces and copy the exports into local constants, as above. Vitest prints a `Benchmark Warning` when a benchmark reads an imported binding too many times.
|
|
110
|
-
- The shared data is in `test/bench/helpers.ts`: `numbers` (100,000 integers), `
|
|
133
|
+
- The shared data is in `test/bench/helpers.ts`: `numbers` (100,000 integers) for every scenario, `small` (1,000 integers) for `<name>/small`, `records` (100,000 objects) only for a key or a selector on objects. The callbacks and values of the scenarios are there too: `double`, `isEven`, `first`, `middle`, `missing`.
|