Skip to content

Commit 0ede9cd

Browse files
chore: Add AsyncIterable benchmarks (#361)
* Update benchmark code * Add AsyncIterable benchmarks * chore: fix lint errors * chore: add dev dependencies --------- Co-authored-by: Cayman <[email protected]>
1 parent 07b995c commit 0ede9cd

7 files changed

+140
-43
lines changed

.benchrc.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Mocha opts
2+
extension: ["ts"]
3+
colors: true
4+
node-option:
5+
- "loader=ts-node/register"
6+
7+
# benchmark opts
8+
threshold: 3
9+
maxMs: 60_000
10+
minRuns: 10

package-lock.json

Lines changed: 8 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@
4949
"prepare": "npm run build",
5050
"pretest": "npm run build",
5151
"pretest:e2e": "npm run build",
52-
"benchmark": "node ./node_modules/.bin/benchmark 'dist/test/benchmark/*.test.js' --local",
52+
"benchmark": "yarn benchmark:files 'test/benchmark/**/*.test.ts'",
53+
"benchmark:files": "NODE_OPTIONS='--max-old-space-size=4096 --loader=ts-node/esm' benchmark --config .benchrc.yaml --defaultBranch master",
5354
"test": "aegir test -f './dist/test/*.spec.js'",
5455
"test:unit": "aegir test -f './dist/test/unit/*.test.js' --target node",
5556
"test:e2e": "aegir test -f './dist/test/e2e/*.spec.js'",
@@ -96,16 +97,18 @@
9697
"@libp2p/peer-id-factory": "^4.0.5",
9798
"@libp2p/peer-store": "^10.0.8",
9899
"@types/node": "^20.11.6",
100+
"abortable-iterator": "^5.1.0",
99101
"aegir": "^42.2.2",
100102
"datastore-core": "^9.2.7",
101103
"delay": "^6.0.0",
102104
"mkdirp": "^3.0.1",
105+
"it-all": "^3.0.6",
103106
"p-defer": "^4.0.0",
104107
"p-event": "^6.0.0",
105108
"p-retry": "^6.2.0",
106109
"p-wait-for": "^5.0.2",
107-
"sinon": "^17.0.1",
108110
"protons": "^7.5.0",
111+
"sinon": "^17.0.1",
109112
"time-cache": "^0.3.0",
110113
"ts-sinon": "^2.0.2"
111114
},

test/benchmark/asyncIterable.test.ts

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import { itBench } from '@dapplion/benchmark'
2+
import { abortableSource } from 'abortable-iterator'
3+
import all from 'it-all'
4+
import { pipe } from 'it-pipe'
5+
6+
/* eslint-disable generator-star-spacing */
7+
8+
describe('abortableSource cost', function () {
9+
const n = 10000
10+
const bytes = new Uint8Array(200)
11+
const controller = new AbortController()
12+
13+
async function* bytesSource (): AsyncGenerator<Uint8Array, void, unknown> {
14+
let i = 0
15+
while (i++ < n) {
16+
yield bytes
17+
}
18+
}
19+
20+
for (let k = 0; k < 5; k++) {
21+
itBench({
22+
id: `async iterate abortable x${k} bytesSource ${n}`,
23+
beforeEach: () => {
24+
let source = bytesSource()
25+
for (let i = 0; i < k; i++) {
26+
source = abortableSource(source, controller.signal)
27+
}
28+
return source
29+
},
30+
fn: async (source) => {
31+
for await (const chunk of source) {
32+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
33+
chunk
34+
}
35+
}
36+
})
37+
}
38+
})
39+
40+
describe('pipe extra iterables cost', function () {
41+
const n = 10000
42+
43+
async function* numberSource (): AsyncGenerator<number, void, unknown> {
44+
let i = 0
45+
while (i < n) {
46+
yield i++
47+
}
48+
}
49+
50+
async function* numberTransform (source: AsyncIterable<number>): AsyncIterable<number> {
51+
for await (const num of source) {
52+
yield num + 1
53+
}
54+
}
55+
56+
itBench({
57+
id: `async iterate pipe x0 transforms ${n}`,
58+
fn: async () => {
59+
await pipe(numberSource, all)
60+
}
61+
})
62+
63+
itBench({
64+
id: `async iterate pipe x1 transforms ${n}`,
65+
fn: async () => {
66+
await pipe(numberSource, numberTransform, all)
67+
}
68+
})
69+
70+
itBench({
71+
id: `async iterate pipe x2 transforms ${n}`,
72+
fn: async () => {
73+
await pipe(
74+
numberSource,
75+
numberTransform,
76+
numberTransform,
77+
all
78+
)
79+
}
80+
})
81+
82+
itBench({
83+
id: `async iterate pipe x4 transforms ${n}`,
84+
fn: async () => {
85+
await pipe(
86+
numberSource,
87+
numberTransform,
88+
numberTransform,
89+
numberTransform,
90+
numberTransform,
91+
all
92+
)
93+
}
94+
})
95+
96+
itBench({
97+
id: `async iterate pipe x8 transforms ${n}`,
98+
fn: async () => {
99+
await pipe(
100+
numberSource,
101+
numberTransform,
102+
numberTransform,
103+
numberTransform,
104+
numberTransform,
105+
numberTransform,
106+
numberTransform,
107+
numberTransform,
108+
numberTransform,
109+
all
110+
)
111+
}
112+
})
113+
})

test/benchmark/index.test.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { itBench, setBenchOpts } from '@dapplion/benchmark'
1+
import { itBench } from '@dapplion/benchmark'
22
import { expect } from 'aegir/chai'
33
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
44
import {
@@ -9,15 +9,7 @@ import {
99
} from '../utils/create-pubsub.js'
1010
import { awaitEvents, checkReceivedSubscriptions, checkReceivedSubscription } from '../utils/events.js'
1111

12-
// eslint-disable-next-line no-only-tests/no-only-tests
13-
describe.only('heartbeat', function () {
14-
this.timeout(0)
15-
setBenchOpts({
16-
maxMs: 200 * 1000,
17-
minMs: 120 * 1000,
18-
minRuns: 200
19-
})
20-
12+
describe('heartbeat', function () {
2113
const topic = 'foobar'
2214
const numTopic = 70
2315
const numPeers = 50

test/benchmark/protobuf.test.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
import crypto from 'node:crypto'
2-
import { itBench, setBenchOpts } from '@dapplion/benchmark'
2+
import { itBench } from '@dapplion/benchmark'
33
import { RPC } from '../../src/message/rpc.js'
44

55
describe('protobuf', function () {
6-
this.timeout(0)
7-
setBenchOpts({
8-
maxMs: 200 * 1000,
9-
minMs: 60 * 1000
10-
})
11-
126
const testCases: Array<{ name: string, length: number }> = [
137
// As of Oct 2023, Attestation length = 281
148
{ name: 'Attestation', length: 300 },

test/benchmark/time-cache.test.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
1-
import { itBench, setBenchOpts } from '@dapplion/benchmark'
1+
import { itBench } from '@dapplion/benchmark'
22
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
33
// @ts-expect-error no types
44
import TimeCache from 'time-cache'
55
import { SimpleTimeCache } from '../../src/utils/time-cache.js'
66

77
// TODO: errors with "Error: root suite not found"
88
describe('npm TimeCache vs SimpleTimeCache', () => {
9-
setBenchOpts({
10-
maxMs: 100 * 1000,
11-
minMs: 60 * 1000,
12-
minRuns: 512
13-
})
14-
159
const iterations = [1_000_000, 4_000_000, 8_000_000, 16_000_000]
1610
const timeCache = new TimeCache({ validity: 1 })
1711
const simpleTimeCache = new SimpleTimeCache({ validityMs: 1000 })

0 commit comments

Comments
 (0)