Skip to content

Commit 4fcb03e

Browse files
committed
bench(useSingle): add benchmark tests
1 parent 5ab96e8 commit 4fcb03e

File tree

1 file changed

+216
-0
lines changed

1 file changed

+216
-0
lines changed
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
// Composables
2+
import { useSingle } from './index'
3+
4+
// Utilities
5+
import { describe, it, expect } from 'vitest'
6+
import { run, compare } from '#v0/utilities/benchmark'
7+
8+
describe('useSingle benchmarks', () => {
9+
it('should benchmark registration operations', async () => {
10+
const context = useSingle('benchmark-test')[2]
11+
12+
const result = await run('register 1000 single items', () => {
13+
for (let i = 0; i < 1000; i++) {
14+
context.register({ value: `item-${i}`, disabled: false })
15+
}
16+
}, 10)
17+
18+
expect(result.name).toBe('register 1000 single items')
19+
expect(result.duration).toBeGreaterThan(0)
20+
expect(result.ops).toBeGreaterThan(0)
21+
22+
console.log(`Single Registration: ${result.ops} ops/sec (${result.duration.toFixed(2)}ms avg)`)
23+
})
24+
25+
it('should benchmark selection operations', async () => {
26+
const context = useSingle('benchmark-test')[2]
27+
28+
// Pre-populate with items
29+
const ids: (string | number)[] = []
30+
for (let i = 0; i < 1000; i++) {
31+
const item = context.register({ value: `item-${i}`, disabled: false })
32+
ids.push(item.id)
33+
}
34+
35+
const result = await run('select 1000 items', () => {
36+
for (const id of ids) {
37+
context.select(id)
38+
}
39+
}, 10)
40+
41+
expect(result.name).toBe('select 1000 items')
42+
expect(result.duration).toBeGreaterThan(0)
43+
expect(result.ops).toBeGreaterThan(0)
44+
45+
console.log(`Selection: ${result.ops} ops/sec (${result.duration.toFixed(2)}ms avg)`)
46+
})
47+
48+
it('should benchmark browse operations', async () => {
49+
const context = useSingle('benchmark-test')[2]
50+
51+
// Pre-populate with items
52+
for (let i = 0; i < 1000; i++) {
53+
context.register({ value: `item-${i}`, disabled: false })
54+
}
55+
56+
const result = await run('browse 1000 values', () => {
57+
for (let i = 0; i < 1000; i++) {
58+
context.browse(`item-${i}`)
59+
}
60+
}, 10)
61+
62+
expect(result.name).toBe('browse 1000 values')
63+
expect(result.duration).toBeGreaterThan(0)
64+
expect(result.ops).toBeGreaterThan(0)
65+
66+
console.log(`Browse: ${result.ops} ops/sec (${result.duration.toFixed(2)}ms avg)`)
67+
})
68+
69+
it('should benchmark single selection operations', async () => {
70+
const context = useSingle('benchmark-test-single', {})[2]
71+
72+
// Pre-populate with items
73+
const ids: (string | number)[] = []
74+
for (let i = 0; i < 100; i++) {
75+
const item = context.register({ value: `item-${i}`, disabled: false })
76+
ids.push(item.id)
77+
}
78+
79+
const result = await run('select single 100 items', () => {
80+
for (const id of ids) {
81+
context.select(id) // Each selection automatically deselects the previous
82+
}
83+
}, 50)
84+
85+
expect(result.name).toBe('select single 100 items')
86+
expect(result.duration).toBeGreaterThan(0)
87+
expect(result.ops).toBeGreaterThan(0)
88+
89+
console.log(`Single Selection: ${result.ops} ops/sec (${result.duration.toFixed(2)}ms avg)`)
90+
})
91+
92+
it('should benchmark reset operations', async () => {
93+
const context = useSingle('benchmark-test')[2]
94+
95+
// Pre-populate with items and selection
96+
for (let i = 0; i < 1000; i++) {
97+
const item = context.register({ value: `item-${i}`, disabled: false })
98+
if (i === 500) context.select(item.id)
99+
}
100+
101+
const result = await run('reset 1000 items', () => {
102+
context.reset()
103+
}, 100)
104+
105+
expect(result.name).toBe('reset 1000 items')
106+
expect(result.duration).toBeGreaterThan(0)
107+
expect(result.ops).toBeGreaterThan(0)
108+
109+
console.log(`Reset: ${result.ops} ops/sec (${result.duration.toFixed(2)}ms avg)`)
110+
})
111+
112+
it('should benchmark mandate operations', async () => {
113+
const context = useSingle('benchmark-test-mandatory', { mandatory: true })[2]
114+
115+
// Pre-populate with items
116+
for (let i = 0; i < 1000; i++) {
117+
context.register({ value: `item-${i}`, disabled: i % 100 === 0 })
118+
}
119+
120+
const result = await run('mandate selection', () => {
121+
context.selectedIds.clear()
122+
context.mandate()
123+
}, 100)
124+
125+
expect(result.name).toBe('mandate selection')
126+
expect(result.duration).toBeGreaterThan(0)
127+
expect(result.ops).toBeGreaterThan(0)
128+
129+
console.log(`Mandate: ${result.ops} ops/sec (${result.duration.toFixed(2)}ms avg)`)
130+
})
131+
132+
it('should compare different single operation types', async () => {
133+
const context = useSingle('benchmark-test')[2]
134+
135+
// Pre-populate for operations
136+
const items: any[] = []
137+
for (let i = 0; i < 100; i++) {
138+
const item = context.register({ value: `item-${i}`, disabled: false })
139+
items.push(item)
140+
}
141+
142+
const results = await compare({
143+
'register 100 single items': () => {
144+
const ctx = useSingle('register-test')[2]
145+
for (let i = 0; i < 100; i++) {
146+
ctx.register({ value: `item-${i}`, disabled: false })
147+
}
148+
},
149+
'select 100 items': () => {
150+
for (const item of items) {
151+
context.select(item.id)
152+
}
153+
},
154+
'browse 100 values': () => {
155+
for (let i = 0; i < 100; i++) {
156+
context.browse(`item-${i}`)
157+
}
158+
},
159+
'reset 100 items': () => {
160+
context.reset()
161+
},
162+
})
163+
164+
expect(results).toHaveLength(4)
165+
166+
console.log('Single operation comparison (fastest to slowest):')
167+
for (const [index, result] of results.entries()) {
168+
console.log(`${index + 1}. ${result.name}: ${result.ops} ops/sec`)
169+
}
170+
})
171+
172+
it('should benchmark different single sizes', async () => {
173+
const sizes = [10, 100, 1000, 5000]
174+
175+
console.log('Single registration performance by collection size:')
176+
177+
for (const size of sizes) {
178+
const context = useSingle(`benchmark-size-${size}`)[2]
179+
180+
const result = await run(`register ${size} single items`, () => {
181+
for (let i = 0; i < size; i++) {
182+
context.register({ value: `item-${i}`, disabled: false })
183+
}
184+
}, 5)
185+
186+
console.log(`Size ${size}: ${result.ops} ops/sec (${result.duration.toFixed(2)}ms avg)`)
187+
188+
expect(result.ops).toBeGreaterThan(0)
189+
}
190+
})
191+
192+
it('should benchmark different single configurations', async () => {
193+
const configs = [
194+
{ name: 'default', options: {} },
195+
{ name: 'mandatory', options: { mandatory: true } },
196+
{ name: 'returnObject', options: { returnObject: true } },
197+
{ name: 'mandatory + returnObject', options: { mandatory: true, returnObject: true } },
198+
]
199+
200+
console.log('Single registration performance by configuration:')
201+
202+
for (const config of configs) {
203+
const context = useSingle(`benchmark-config-${config.name}`, config.options)[2]
204+
205+
const result = await run(`register 500 items (${config.name})`, () => {
206+
for (let i = 0; i < 500; i++) {
207+
context.register({ value: `item-${i}`, disabled: false })
208+
}
209+
}, 5)
210+
211+
console.log(`${config.name}: ${result.ops} ops/sec (${result.duration.toFixed(2)}ms avg)`)
212+
213+
expect(result.ops).toBeGreaterThan(0)
214+
}
215+
})
216+
})

0 commit comments

Comments
 (0)