@thi.ng/bench 3.4.33 → 3.5.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/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2024-03-09T09:18:17Z
3
+ - **Last updated**: 2024-03-13T14:04:31Z
4
4
  - **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
5
5
 
6
6
  All notable changes to this project will be documented in this file.
@@ -9,6 +9,16 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
9
9
  **Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
10
10
  and/or version bumps of transitive dependencies.
11
11
 
12
+ ## [3.5.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/bench@3.5.0) (2024-03-13)
13
+
14
+ #### 🚀 Features
15
+
16
+ - add frequency stat (i.e. ops/sec) ([0e6576a](https://github.com/thi-ng/umbrella/commit/0e6576a))
17
+ - add `BenchmarkOpts.extSize`
18
+ - update `benchmark()`
19
+ - update all formatters
20
+ - add `setPrecision()` to adjust float formatter
21
+
12
22
  ### [3.4.28](https://github.com/thi-ng/umbrella/tree/@thi.ng/bench@3.4.28) (2024-02-22)
13
23
 
14
24
  #### ♻️ Refactoring
package/README.md CHANGED
@@ -78,7 +78,7 @@ For Node.js REPL:
78
78
  const bench = await import("@thi.ng/bench");
79
79
  ```
80
80
 
81
- Package sizes (brotli'd, pre-treeshake): ESM: 2.07 KB
81
+ Package sizes (brotli'd, pre-treeshake): ESM: 2.13 KB
82
82
 
83
83
  ## Dependencies
84
84
 
@@ -107,35 +107,45 @@ directory are using this package:
107
107
 
108
108
  ### Basic usage
109
109
 
110
- ```ts
111
- import { timed, bench, benchmark } from "@thi.ng/bench";
112
-
113
- // test functions
114
- const fib = (n) => n > 2 ? fib(n - 1) + fib(n - 2) : n > 0 ? 1 : 0;
110
+ ```ts id:test-functions
111
+ // functions to benchmark...
112
+ const fib = (n: number) =>
113
+ n > 2
114
+ ? fib(n - 1) + fib(n - 2)
115
+ : n > 0
116
+ ? 1
117
+ : 0;
115
118
 
116
- const fib2 = (n) => {
119
+ const fib2 = (n: number) => {
117
120
  const res = [0, 1];
118
121
  for(let i = 2; i <= n; i++) {
119
122
  res[i] = res[i - 1] + res[i - 2];
120
123
  }
121
124
  return res[n];
122
125
  };
126
+ ```
127
+
128
+ ```ts tangle:export/readme1.ts
129
+ import { timed, bench } from "@thi.ng/bench";
130
+
131
+ <<test-functions>>
123
132
 
124
133
  // measure single execution time
125
- timed(() => fib(40));
126
- // 714ms
134
+ console.log(timed(() => fib(40)));
135
+ // 318.86ms
127
136
  // 102334155
128
- timed(() => fib2(40));
129
- // 0ms
137
+
138
+ console.log(timed(() => fib2(40)));
139
+ // 0.05ms
130
140
  // 102334155
131
141
 
132
142
  // measure 1mil iterations (default)
133
- bench(() => fib(10), 1e6);
134
- // 395ms
143
+ console.log(bench(() => fib(10), 1e6));
144
+ // 157.41ms
135
145
  // 55
136
146
 
137
- bench(() => fib2(10), 1e6);
138
- // 53ms
147
+ console.log(bench(() => fib2(10), 1e6));
148
+ // 95.97ms
139
149
  // 55
140
150
  ```
141
151
 
@@ -153,32 +163,34 @@ for configuration options.
153
163
  Also see the [formatting](#output-formatting) section below for other output
154
164
  options. This example uses the default format...
155
165
 
156
- ```ts
166
+ ```ts tangle:export/readme2.ts
157
167
  import { benchmark } from "@thi.ng/bench";
158
168
 
159
- // fib() function is from previous example above...
169
+ <<test-functions>>
160
170
 
161
171
  benchmark(() => fib(40), { title: "fib", iter: 10, warmup: 5 });
162
172
  // benchmarking: fib
163
- // warmup... 3707.17ms (5 runs)
164
- // executing...
165
- // total: 7333.72ms, runs: 10
166
- // mean: 733.37ms, median: 733.79ms, range: [728.58..743.43]
167
- // q1: 730.98ms, q3: 735.03ms
168
- // sd: 0.54%
173
+ // warmup... 1480.79ms (5 runs)
174
+ // total: 2917.41ms, runs: 10 (@ 1 calls/iter)
175
+ // freq: 3.43 ops/sec
176
+ // mean: 291.74ms, median: 291.67ms, range: [291.51..292.58]
177
+ // q1: 291.55ms, q3: 291.79ms
178
+ // sd: 0.10%
169
179
 
170
180
  // also returns results:
171
181
  // {
172
182
  // title: "fib",
173
183
  // iter: 10,
174
- // total: 7333.72402,
175
- // mean: 733.372402,
176
- // median: 733.794194,
177
- // min: 728.5808,
178
- // max: 743.432538,
179
- // q1: 730.980115,
180
- // q3: 735.025314,
181
- // sd: 0.542200865574415
184
+ // size: 1,
185
+ // total: 2917.4060010000003,
186
+ // freq: 3.4277025537660157,
187
+ // mean: 291.74060010000005,
188
+ // median: 291.668125,
189
+ // min: 291.50624999999997,
190
+ // max: 292.581834,
191
+ // q1: 291.55116699999996,
192
+ // q3: 291.788417,
193
+ // sd: 0.10295312107365955,
182
194
  // }
183
195
  ```
184
196
 
@@ -187,10 +199,10 @@ benchmark(() => fib(40), { title: "fib", iter: 10, warmup: 5 });
187
199
  Multiple benchmarks can be run sequentially as suite (also returns an array of
188
200
  all results):
189
201
 
190
- ```ts
202
+ ```ts tangle:export/readme3.ts
191
203
  import { suite, FORMAT_MD } from "@thi.ng/bench";
192
204
 
193
- // fib2() function defined in earlier example above...
205
+ <<test-functions>>
194
206
 
195
207
  suite(
196
208
  [
@@ -202,22 +214,22 @@ suite(
202
214
  { iter: 10, size: 100000, warmup: 5, format: FORMAT_MD }
203
215
  )
204
216
 
205
- // | Title| Iter| Size| Total| Mean| Median| Min| Max| Q1| Q3| SD%|
206
- // |------------------------|-------:|-------:|-----------:|-------:|-------:|-------:|-------:|-------:|-------:|-------:|
207
- // | fib2(10)| 10| 100000| 54.34| 5.43| 5.15| 4.40| 8.14| 4.84| 6.67| 20.32|
208
- // | fib2(20)| 10| 100000| 121.24| 12.12| 12.13| 11.73| 12.91| 11.93| 12.35| 2.61|
209
- // | fib2(30)| 10| 100000| 152.98| 15.30| 14.51| 13.93| 20.77| 14.35| 16.35| 12.65|
210
- // | fib2(40)| 10| 100000| 164.79| 16.48| 15.60| 15.01| 19.27| 15.42| 18.80| 9.34|
217
+ // | Title| Iter| Size| Total| Frequency| Mean| Median| Min| Max| Q1| Q3| SD%|
218
+ // |------------------------|-------:|-------:|-----------:|-----------:|-------:|-------:|-------:|-------:|-------:|-------:|-------:|
219
+ // | fib2(10)| 10| 100000| 93.25| 10723774.45| 9.33| 9.25| 8.94| 10.27| 9.03| 9.46| 4.15|
220
+ // | fib2(20)| 10| 100000| 110.73| 9030823.33| 11.07| 11.02| 10.91| 11.56| 10.92| 11.10| 1.76|
221
+ // | fib2(30)| 10| 100000| 175.10| 5711056.26| 17.51| 17.58| 17.03| 17.65| 17.50| 17.60| 0.96|
222
+ // | fib2(40)| 10| 100000| 200.01| 4999765.64| 20.00| 19.71| 19.34| 21.78| 19.55| 19.91| 3.90|
211
223
  ```
212
224
 
213
225
  Same table as actual Markdown:
214
226
 
215
- | Title| Iter| Size| Total| Mean| Median| Min| Max| Q1| Q3| SD%|
216
- |------------------------|-------:|-------:|-----------:|-------:|-------:|-------:|-------:|-------:|-------:|-------:|
217
- | fib2(10)| 10| 100000| 54.34| 5.43| 5.15| 4.40| 8.14| 4.84| 6.67| 20.32|
218
- | fib2(20)| 10| 100000| 121.24| 12.12| 12.13| 11.73| 12.91| 11.93| 12.35| 2.61|
219
- | fib2(30)| 10| 100000| 152.98| 15.30| 14.51| 13.93| 20.77| 14.35| 16.35| 12.65|
220
- | fib2(40)| 10| 100000| 164.79| 16.48| 15.60| 15.01| 19.27| 15.42| 18.80| 9.34|
227
+ | Title| Iter| Size| Total| Frequency| Mean| Median| Min| Max| Q1| Q3| SD%|
228
+ |------------------------|-------:|-------:|-----------:|-----------:|-------:|-------:|-------:|-------:|-------:|-------:|-------:|
229
+ | fib2(10)| 10| 100000| 93.25| 10723774.45| 9.33| 9.25| 8.94| 10.27| 9.03| 9.46| 4.15|
230
+ | fib2(20)| 10| 100000| 110.73| 9030823.33| 11.07| 11.02| 10.91| 11.56| 10.92| 11.10| 1.76|
231
+ | fib2(30)| 10| 100000| 175.10| 5711056.26| 17.51| 17.58| 17.03| 17.65| 17.50| 17.60| 0.96|
232
+ | fib2(40)| 10| 100000| 200.01| 4999765.64| 20.00| 19.71| 19.34| 21.78| 19.55| 19.91| 3.90|
221
233
 
222
234
  ### Output formatting
223
235
 
package/api.d.ts CHANGED
@@ -19,6 +19,18 @@ export interface BenchmarkOpts {
19
19
  * @defaultValue 1
20
20
  */
21
21
  size: number;
22
+ /**
23
+ * Externally defined batch size, similar to {@link BenchmarkOpts.size},
24
+ * i.e. calls per iteration. However, this option is ONLY used for computing
25
+ * {@link BenchmarkResult.freq} and has no impact on actual benchmark
26
+ * execution.
27
+ *
28
+ * @remarks
29
+ * This option is only to be used if the benchmarked function uses internal
30
+ * looping to execute multiple iterations. E.g. if internally executing N
31
+ * iterations, `extSize` should be set to that number.
32
+ */
33
+ extSize: number;
22
34
  /**
23
35
  * Number of warmup iterations (not included in results).
24
36
  *
@@ -56,28 +68,38 @@ export interface BenchmarkResult {
56
68
  */
57
69
  total: number;
58
70
  /**
59
- * Mean execution time (in ms)
71
+ * Frequency aka number of ops per second
72
+ */
73
+ freq: number;
74
+ /**
75
+ * Mean execution time (in ms) per iteration (batch of
76
+ * {@link BenchmarkResult.size} calls)
60
77
  */
61
78
  mean: number;
62
79
  /**
63
- * Median execution time (in ms)
80
+ * Median execution time (in ms) per iteration (batch of
81
+ * {@link BenchmarkResult.size} calls)
64
82
  */
65
83
  median: number;
66
84
  /**
67
- * Min execution time (in ms)
85
+ * Min execution time (in ms) per iteration (batch of
86
+ * {@link BenchmarkResult.size} calls)
68
87
  */
69
88
  min: number;
70
89
  /**
71
- * Max execution time (in ms)
90
+ * Max execution time (in ms) per iteration (batch of
91
+ * {@link BenchmarkResult.size} calls)
72
92
  */
73
93
  max: number;
74
94
  /**
75
- * First quartile execution time (in ms). I.e. 25% of all runs were
95
+ * First quartile execution time (in ms) per iteration (batch of
96
+ * {@link BenchmarkResult.size} calls). I.e. 25% of all runs were
76
97
  * faster/equal to this measurement.
77
98
  */
78
99
  q1: number;
79
100
  /**
80
- * Third quartile execution time (in ms). I.e. 25% of all runs were
101
+ * Third quartile execution time (in ms) per iteration (batch of
102
+ * {@link BenchmarkResult.size} calls). I.e. 25% of all runs were
81
103
  * equal/slower than this measurement.
82
104
  */
83
105
  q3: number;
@@ -131,6 +153,7 @@ export interface Benchmark {
131
153
  */
132
154
  opts?: Partial<OptsWithoutTitle>;
133
155
  }
156
+ export declare const setPrecision: (prec: number) => number;
134
157
  export declare const FLOAT: (x: number) => string;
135
158
  export declare const EMPTY: () => string;
136
159
  //# sourceMappingURL=api.d.ts.map
package/api.js CHANGED
@@ -1,6 +1,9 @@
1
- const FLOAT = (x) => x.toFixed(2);
1
+ let PRECISION = 2;
2
+ const setPrecision = (prec) => PRECISION = prec;
3
+ const FLOAT = (x) => x.toFixed(PRECISION);
2
4
  const EMPTY = () => "";
3
5
  export {
4
6
  EMPTY,
5
- FLOAT
7
+ FLOAT,
8
+ setPrecision
6
9
  };
package/benchmark.js CHANGED
@@ -4,13 +4,14 @@ const DEFAULT_OPTS = {
4
4
  title: "benchmark",
5
5
  iter: 1e3,
6
6
  size: 1,
7
+ extSize: 1,
7
8
  warmup: 10,
8
9
  output: true,
9
10
  format: FORMAT_DEFAULT
10
11
  };
11
12
  const benchmark = (fn, opts) => {
12
13
  const _opts = { ...DEFAULT_OPTS, ...opts };
13
- const { iter, size, warmup, output, format } = _opts;
14
+ let { iter, size, extSize, warmup, output, format } = _opts;
14
15
  output && outputString(format.start(_opts));
15
16
  const t = benchResult(fn, warmup * size)[1];
16
17
  output && outputString(format.warmup(t, _opts));
@@ -20,12 +21,13 @@ const benchmark = (fn, opts) => {
20
21
  }
21
22
  samples.sort((a, b) => a - b);
22
23
  const total = samples.reduce((acc, x) => acc + x, 0);
24
+ const freq = iter * size * extSize * 1e3 / total;
23
25
  const mean = total / iter;
24
26
  const median = samples[iter >> 1];
25
27
  const min = samples[0];
26
28
  const max = samples[iter - 1];
27
- const q1 = samples[Math.ceil(iter * 0.25)];
28
- const q3 = samples[Math.ceil(iter * 0.75)];
29
+ const q1 = samples[Math.floor(iter * 0.25)];
30
+ const q3 = samples[Math.floor(iter * 0.75)];
29
31
  const sd = Math.sqrt(
30
32
  samples.reduce((acc, x) => acc + (mean - x) ** 2, 0) / iter
31
33
  ) / mean * 100;
@@ -34,6 +36,7 @@ const benchmark = (fn, opts) => {
34
36
  iter,
35
37
  size,
36
38
  total,
39
+ freq,
37
40
  mean,
38
41
  median,
39
42
  min,
package/format/csv.js CHANGED
@@ -1,10 +1,11 @@
1
1
  import { EMPTY, FLOAT } from "../api.js";
2
2
  const FORMAT_CSV = {
3
- prefix: () => `Title,Iterations,Size,Total,Mean,Median,Min,Max,Q1,Q3,SD%`,
3
+ prefix: () => `Title,Iterations,Size,Total,Frequency,Mean,Median,Min,Max,Q1,Q3,SD%`,
4
4
  start: EMPTY,
5
5
  warmup: EMPTY,
6
6
  result: (res) => `"${res.title}",${res.iter},${res.size},${[
7
7
  res.total,
8
+ res.freq,
8
9
  res.mean,
9
10
  res.median,
10
11
  res.min,
package/format/default.js CHANGED
@@ -3,9 +3,10 @@ const FORMAT_DEFAULT = {
3
3
  prefix: EMPTY,
4
4
  start: ({ title }) => `benchmarking: ${title}`,
5
5
  warmup: (t, { warmup }) => ` warmup... ${FLOAT(t)}ms (${warmup} runs)`,
6
- result: ({ iter, size, total, mean, median, min, max, q1, q3, sd }) => (
6
+ result: ({ iter, size, total, freq, mean, median, min, max, q1, q3, sd }) => (
7
7
  // prettier-ignore
8
8
  ` total: ${FLOAT(total)}ms, runs: ${iter} (@ ${size} calls/iter)
9
+ freq: ${FLOAT(freq)} ops/sec
9
10
  mean: ${FLOAT(mean)}ms, median: ${FLOAT(median)}ms, range: [${FLOAT(min)}..${FLOAT(max)}]
10
11
  q1: ${FLOAT(q1)}ms, q3: ${FLOAT(q3)}ms
11
12
  sd: ${FLOAT(sd)}%`
@@ -4,7 +4,7 @@ const pad = (w) => {
4
4
  const column = $n(w, " ");
5
5
  return (x) => {
6
6
  const s = typeof x === "number" ? FLOAT(x) : x;
7
- return s.length < w ? column.substr(0, w - s.length) + s : s.substr(0, w);
7
+ return s.length < w ? column.substring(0, w - s.length) + s : s.substring(0, w);
8
8
  };
9
9
  };
10
10
  const c24 = pad(24);
@@ -13,8 +13,8 @@ const c8 = pad(8);
13
13
  const d24 = $n(24);
14
14
  const d12 = $n(11) + ":";
15
15
  const d8 = $n(7) + ":";
16
- const COLUMNS = [c24, c8, c8, c12, c8, c8, c8, c8, c8, c8, c8];
17
- const DASHES = [d24, d8, d8, d12, d8, d8, d8, d8, d8, d8, d8];
16
+ const COLUMNS = [c24, c8, c8, c12, c12, c8, c8, c8, c8, c8, c8, c8];
17
+ const DASHES = [d24, d8, d8, d12, d12, d8, d8, d8, d8, d8, d8, d8];
18
18
  const row = (cols) => `|${cols.map((x, i) => COLUMNS[i](x)).join("|")}|`;
19
19
  const FORMAT_MD = {
20
20
  prefix: () => row([
@@ -22,6 +22,7 @@ const FORMAT_MD = {
22
22
  "Iter",
23
23
  "Size",
24
24
  "Total",
25
+ "Frequency",
25
26
  "Mean",
26
27
  "Median",
27
28
  "Min",
@@ -38,6 +39,7 @@ const FORMAT_MD = {
38
39
  "" + res.iter,
39
40
  "" + res.size,
40
41
  res.total,
42
+ res.freq,
41
43
  res.mean,
42
44
  res.median,
43
45
  res.min,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/bench",
3
- "version": "3.4.33",
3
+ "version": "3.5.0",
4
4
  "description": "Benchmarking & profiling utilities w/ various statistics & formatters (CSV, JSON, Markdown etc.)",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -36,17 +36,17 @@
36
36
  "tool:tangle": "../../node_modules/.bin/tangle src/**/*.ts"
37
37
  },
38
38
  "dependencies": {
39
- "@thi.ng/api": "^8.9.29"
39
+ "@thi.ng/api": "^8.9.30"
40
40
  },
41
41
  "devDependencies": {
42
- "@microsoft/api-extractor": "^7.40.1",
43
- "@thi.ng/testament": "^0.4.22",
44
- "@types/node": "^20.11.17",
45
- "esbuild": "^0.20.0",
42
+ "@microsoft/api-extractor": "^7.42.3",
43
+ "@thi.ng/testament": "^0.4.23",
44
+ "@types/node": "^20.11.26",
45
+ "esbuild": "^0.20.1",
46
46
  "rimraf": "^5.0.5",
47
47
  "tools": "^0.0.1",
48
- "typedoc": "^0.25.7",
49
- "typescript": "^5.3.3"
48
+ "typedoc": "^0.25.12",
49
+ "typescript": "^5.4.2"
50
50
  },
51
51
  "keywords": [
52
52
  "benchmark",
@@ -120,5 +120,5 @@
120
120
  ],
121
121
  "year": 2018
122
122
  },
123
- "gitHead": "69100942474942f7446ac645d59d91e7dfc352f9\n"
123
+ "gitHead": "7f3fcbd6c0462b0ce45afa141fe163d1f297fd51\n"
124
124
  }
package/profiler.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { FnAny, IDeref, IEnable, IObjectOf, IReset } from "@thi.ng/api";
2
2
  import type { Timestamp } from "./api.js";
3
- interface Profile {
3
+ export interface Profile {
4
4
  t0: Timestamp[];
5
5
  total: Timestamp;
6
6
  calls: number;
@@ -103,26 +103,26 @@ export declare class Profiler implements IDeref<IObjectOf<ProfileResult>>, IEnab
103
103
  * no-op.
104
104
  *
105
105
  * * @example
106
- * ```ts
106
+ * ```ts tangle:../export/profiler.ts
107
107
  * import { Profiler } from "@thi.ng/bench";
108
108
  *
109
109
  * const profiler = new Profiler();
110
110
  *
111
111
  * // recursive function
112
- * const countdown = (n, acc = []) => {
112
+ * const countdown = (n: number, acc: number[] = []) => {
113
113
  * profiler.start("countdown");
114
114
  * if (n > 0) countdown(n - 1, (acc.push(n),acc));
115
115
  * profiler.end("countdown");
116
116
  * return acc;
117
117
  * }
118
118
  *
119
- * countdown(10);
119
+ * console.log(countdown(10));
120
120
  * // [ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]
121
121
  *
122
- * countdown(5);
122
+ * console.log(countdown(5));
123
123
  * // [ 5, 4, 3, 2, 1 ]
124
124
  *
125
- * profiler.deref()
125
+ * console.log(profiler.deref());
126
126
  * // {
127
127
  * // countdown: {
128
128
  * // id: 'countdown',
@@ -171,7 +171,7 @@ export declare class Profiler implements IDeref<IObjectOf<ProfileResult>>, IEnab
171
171
  * `fn`.
172
172
  *
173
173
  * @example
174
- * ```ts
174
+ * ```ts tangle:../export/profiler-wrap.ts
175
175
  * import { Profiler } from "@thi.ng/bench";
176
176
  *
177
177
  * const profiler = new Profiler();
@@ -181,10 +181,10 @@ export declare class Profiler implements IDeref<IObjectOf<ProfileResult>>, IEnab
181
181
  * (vec: number[]) => vec.reduce((acc, x) => acc + x, 0)
182
182
  * );
183
183
  *
184
- * sum([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
184
+ * console.log(sum([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]));
185
185
  * // 55
186
186
  *
187
- * profiler.deref()
187
+ * console.log(profiler.deref());
188
188
  * // {
189
189
  * // sum: {
190
190
  * // id: 'sum',
@@ -230,5 +230,4 @@ export declare class Profiler implements IDeref<IObjectOf<ProfileResult>>, IEnab
230
230
  maxDepth: number;
231
231
  };
232
232
  }
233
- export {};
234
233
  //# sourceMappingURL=profiler.d.ts.map
package/profiler.js CHANGED
@@ -94,26 +94,26 @@ class Profiler {
94
94
  * no-op.
95
95
  *
96
96
  * * @example
97
- * ```ts
97
+ * ```ts tangle:../export/profiler.ts
98
98
  * import { Profiler } from "@thi.ng/bench";
99
99
  *
100
100
  * const profiler = new Profiler();
101
101
  *
102
102
  * // recursive function
103
- * const countdown = (n, acc = []) => {
103
+ * const countdown = (n: number, acc: number[] = []) => {
104
104
  * profiler.start("countdown");
105
105
  * if (n > 0) countdown(n - 1, (acc.push(n),acc));
106
106
  * profiler.end("countdown");
107
107
  * return acc;
108
108
  * }
109
109
  *
110
- * countdown(10);
110
+ * console.log(countdown(10));
111
111
  * // [ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]
112
112
  *
113
- * countdown(5);
113
+ * console.log(countdown(5));
114
114
  * // [ 5, 4, 3, 2, 1 ]
115
115
  *
116
- * profiler.deref()
116
+ * console.log(profiler.deref());
117
117
  * // {
118
118
  * // countdown: {
119
119
  * // id: 'countdown',
@@ -197,7 +197,7 @@ class Profiler {
197
197
  * `fn`.
198
198
  *
199
199
  * @example
200
- * ```ts
200
+ * ```ts tangle:../export/profiler-wrap.ts
201
201
  * import { Profiler } from "@thi.ng/bench";
202
202
  *
203
203
  * const profiler = new Profiler();
@@ -207,10 +207,10 @@ class Profiler {
207
207
  * (vec: number[]) => vec.reduce((acc, x) => acc + x, 0)
208
208
  * );
209
209
  *
210
- * sum([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
210
+ * console.log(sum([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]));
211
211
  * // 55
212
212
  *
213
- * profiler.deref()
213
+ * console.log(profiler.deref());
214
214
  * // {
215
215
  * // sum: {
216
216
  * // id: 'sum',