Skip to content

Commit c218cd5

Browse files
authored
Merge pull request #6 from MavonEngine/testing/init-bench
init benchmarking in core
2 parents 8c23c88 + 36ddadd commit c218cd5

5 files changed

Lines changed: 188 additions & 0 deletions

File tree

packages/core/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"dev": "rm -f tsconfig.build.tsbuildinfo && tsc -p tsconfig.build.json --watch",
3838
"lint": "eslint .",
3939
"lint:fix": "eslint . --fix",
40+
"bench": "vitest bench",
4041
"test": "vitest",
4142
"test:ui": "vitest --ui --coverage.enabled true --coverage.reporter html",
4243
"test:coverage": "vitest --coverage.enabled true --coverage.reporter json-summary",
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { bench, describe } from 'vitest'
2+
import BandwidthTracker from '../../../../src/Networking/Server/Stats/BandwidthTracker'
3+
4+
describe('BandwidthTracker', () => {
5+
bench('recordSent — single id', () => {
6+
const tracker = new BandwidthTracker()
7+
tracker.recordSent('client-1', 128)
8+
})
9+
10+
bench('recordSent — accumulation (same id, 100 calls)', () => {
11+
const tracker = new BandwidthTracker()
12+
for (let i = 0; i < 100; i++) {
13+
tracker.recordSent('client-1', 128)
14+
}
15+
})
16+
17+
bench('recordSent — 50 unique ids', () => {
18+
const tracker = new BandwidthTracker()
19+
for (let i = 0; i < 50; i++) {
20+
tracker.recordSent(`client-${i}`, 128)
21+
}
22+
})
23+
24+
bench('getBandwidthUsage — existing id', () => {
25+
const tracker = new BandwidthTracker()
26+
tracker.recordSent('client-1', 128)
27+
tracker.getBandwidthUsage('client-1')
28+
})
29+
30+
bench('getBandwidthUsage — missing id', () => {
31+
const tracker = new BandwidthTracker()
32+
tracker.getBandwidthUsage('client-1')
33+
})
34+
35+
bench('reset — 50 entries', () => {
36+
const tracker = new BandwidthTracker()
37+
for (let i = 0; i < 50; i++) {
38+
tracker.recordSent(`client-${i}`, 128)
39+
tracker.recordReceived(`client-${i}`, 64)
40+
}
41+
tracker.reset()
42+
})
43+
})
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import type EntityState from '../../src/World/Entity/State'
2+
import { bench, describe } from 'vitest'
3+
import NetworkedActor from '../../src/Networking/NetworkedActor'
4+
import NetworkedEntityState from '../../src/Networking/NetworkedEntityState'
5+
import { syncStateStack } from '../../src/Networking/syncState'
6+
7+
class TestActor extends NetworkedActor {
8+
$typeName = 'testActor'
9+
updateFromNetwork = (_data: object) => {}
10+
update(_delta: number): void {}
11+
}
12+
13+
class StateA extends NetworkedEntityState {
14+
readonly stateName = 'stateA'
15+
update(_delta: number): EntityState | void {}
16+
}
17+
18+
class StateB extends NetworkedEntityState {
19+
readonly stateName = 'stateB'
20+
update(_delta: number): EntityState | void {}
21+
}
22+
23+
const factories = {
24+
stateA: (entity: TestActor) => new StateA(entity),
25+
stateB: (entity: TestActor) => new StateB(entity),
26+
}
27+
28+
describe('syncStateStack', () => {
29+
bench('no-op (states already match)', () => {
30+
const actor = new TestActor()
31+
actor.state.push(new StateA(actor))
32+
syncStateStack(actor, [{ stateName: 'stateA' }], factories)
33+
})
34+
35+
bench('full replacement (stateB → stateA)', () => {
36+
const actor = new TestActor()
37+
actor.state.push(new StateB(actor))
38+
syncStateStack(actor, [{ stateName: 'stateA' }], factories)
39+
})
40+
41+
bench('add to stack (1 → 2 states)', () => {
42+
const actor = new TestActor()
43+
actor.state.push(new StateA(actor))
44+
syncStateStack(actor, [{ stateName: 'stateA' }, { stateName: 'stateB' }], factories)
45+
})
46+
47+
bench('remove from stack (2 → 1 states)', () => {
48+
const actor = new TestActor()
49+
actor.state.push(new StateA(actor))
50+
actor.state.push(new StateB(actor))
51+
syncStateStack(actor, [{ stateName: 'stateA' }], factories)
52+
})
53+
54+
bench('clear all states (2 → 0)', () => {
55+
const actor = new TestActor()
56+
actor.state.push(new StateA(actor))
57+
actor.state.push(new StateB(actor))
58+
syncStateStack(actor, [], factories)
59+
})
60+
})
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { bench, describe } from 'vitest'
2+
import EventEmitter from '../../src/Utils/EventEmitter'
3+
4+
describe('EventEmitter', () => {
5+
bench('trigger — unknown event (no listeners)', () => {
6+
const emitter = new EventEmitter()
7+
emitter.trigger('tick')
8+
})
9+
10+
bench('trigger — 1 listener', () => {
11+
const emitter = new EventEmitter()
12+
emitter.on('tick', () => {})
13+
emitter.trigger('tick', { delta: 0.016 })
14+
})
15+
16+
bench('trigger — 10 listeners', () => {
17+
const emitter = new EventEmitter()
18+
for (let i = 0; i < 10; i++) {
19+
emitter.on('tick', () => {})
20+
}
21+
emitter.trigger('tick', { delta: 0.016 })
22+
})
23+
24+
bench('on — register listener', () => {
25+
const emitter = new EventEmitter()
26+
emitter.on('tick', () => {})
27+
})
28+
29+
bench('off — remove 1 of 10 listeners', () => {
30+
const emitter = new EventEmitter()
31+
const cb = () => {}
32+
for (let i = 0; i < 9; i++) emitter.on('tick', () => {})
33+
emitter.on('tick', cb)
34+
emitter.off('tick', cb)
35+
})
36+
})
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { bench, describe } from 'vitest'
2+
import Actor from '../../src/World/Actor'
3+
import EntityState from '../../src/World/Entity/State'
4+
import StateManager from '../../src/World/StateManager'
5+
6+
class DummyActor extends Actor {
7+
update() {}
8+
}
9+
10+
class NoopState extends EntityState {
11+
update(_delta: number): EntityState | void {}
12+
}
13+
14+
class TransitionState extends EntityState {
15+
private next: EntityState
16+
17+
constructor(entity: DummyActor, next: EntityState) {
18+
super(entity)
19+
this.next = next
20+
}
21+
22+
update(_delta: number): EntityState | void {
23+
return this.next
24+
}
25+
}
26+
27+
describe('StateManager.update', () => {
28+
bench('empty state stack (no-op)', () => {
29+
const actor = new DummyActor()
30+
const manager = new StateManager()
31+
manager.update(0.016, actor)
32+
})
33+
34+
bench('one state, returns void', () => {
35+
const actor = new DummyActor()
36+
const manager = new StateManager()
37+
manager.state.push(new NoopState(actor))
38+
manager.update(0.016, actor)
39+
})
40+
41+
bench('one state, returns new state (triggers push)', () => {
42+
const actor = new DummyActor()
43+
const manager = new StateManager()
44+
const next = new NoopState(actor)
45+
manager.state.push(new TransitionState(actor, next))
46+
manager.update(0.016, actor)
47+
})
48+
})

0 commit comments

Comments
 (0)