Skip to content

Instantly share code, notes, and snippets.

@nandordudas
Last active August 13, 2024 07:38
Show Gist options
  • Save nandordudas/1e0998c12f58e789cd8505e3cbeeb210 to your computer and use it in GitHub Desktop.
Save nandordudas/1e0998c12f58e789cd8505e3cbeeb210 to your computer and use it in GitHub Desktop.
import { bench, describe } from 'vitest'
describe.each([
{ time: 0, iterations: 100_000, warmupTime: 100, warmupIterations: 1_000 },
{ time: 0, iterations: 100_000, warmupTime: 100, warmupIterations: 0 },
])('vector2D operations with various inputs $warmupIterations', (benchOptions) => {
describe.each([
{ name: 'Small integers', value: { x: 1, y: 2 } },
{ name: 'Large integers', value: { x: 1000000, y: 2000000 } },
{ name: 'Floating point', value: { x: 3.14159, y: 2.71828 } },
{ name: 'Very small floating point', value: { x: 0.00000001, y: 0.00000002 } },
{ name: 'Mixed values', value: { x: 42, y: 0.42 } },
{ name: 'Zero values', value: { x: 0, y: 0 } },
{ name: 'Negative values', value: { x: -5, y: -10 } },
])(`input: $name`, ({ value }) => {
const vector2DArray = new Vector2DArray(0, 0)
const vector2DObject = new Vector2DObject(0, 0)
const vector2DInstance = new Vector2DInstance(0, 0)
const vector2DObjectCachedMap = new Vector2DObjectCachedMap(0, 0)
const vector2DObjectCachedWeakMap = new Vector2DObjectCachedWeakMap(0, 0)
const vectorInput = new Vector2DInstance(value.x, value.y)
const arrayInput: [number, number] = [value.x, value.y]
const objectInput = { x: value.x, y: value.y }
bench('vector2DArray', () => {
vector2DArray.add(arrayInput).add(arrayInput).add(arrayInput).add(arrayInput)
}, benchOptions)
bench('vector2DObject', () => {
vector2DObject.add(objectInput).add(objectInput).add(objectInput).add(objectInput)
}, benchOptions)
bench('vector2DInstance', () => {
vector2DInstance.add(vectorInput).add(vectorInput).add(vectorInput).add(vectorInput)
}, benchOptions)
bench('vector2DObjectCachedMap', () => {
vector2DObjectCachedMap.add(objectInput).add(objectInput).add(objectInput).add(objectInput)
}, benchOptions)
bench('vector2DObjectCachedWeakMap', () => {
vector2DObjectCachedWeakMap.add(objectInput).add(objectInput).add(objectInput).add(objectInput)
}, benchOptions)
})
describe('chaining many small additions', () => {
const vector2DArray = new Vector2DArray(0, 0)
const vector2DObject = new Vector2DObject(0, 0)
const vector2DInstance = new Vector2DInstance(0, 0)
const vector2DObjectCachedMap = new Vector2DObjectCachedMap(0, 0)
const vector2DObjectCachedWeakMap = new Vector2DObjectCachedWeakMap(0, 0)
const vectorInput = new Vector2DInstance(0.1, 0.1)
const arrayInput: [number, number] = [0.1, 0.1]
const objectInput = { x: 0.1, y: 0.1 }
bench('vector2DArray', () => {
vector2DArray
.add(arrayInput).add(arrayInput).add(arrayInput).add(arrayInput).add(arrayInput)
.add(arrayInput).add(arrayInput).add(arrayInput).add(arrayInput).add(arrayInput)
}, benchOptions)
bench('vector2DObject', () => {
vector2DObject
.add(objectInput).add(objectInput).add(objectInput).add(objectInput).add(objectInput)
.add(objectInput).add(objectInput).add(objectInput).add(objectInput).add(objectInput)
}, benchOptions)
bench('vector2DInstance', () => {
vector2DInstance
.add(vectorInput).add(vectorInput).add(vectorInput).add(vectorInput).add(vectorInput)
.add(vectorInput).add(vectorInput).add(vectorInput).add(vectorInput).add(vectorInput)
}, benchOptions)
bench('vector2DObjectCached', () => {
vector2DObjectCachedMap
.add(objectInput).add(objectInput).add(objectInput).add(objectInput).add(objectInput)
.add(objectInput).add(objectInput).add(objectInput).add(objectInput).add(objectInput)
}, benchOptions)
bench('vector2DObjectCachedWeakMap', () => {
vector2DObjectCachedWeakMap
.add(objectInput).add(objectInput).add(objectInput).add(objectInput).add(objectInput)
.add(objectInput).add(objectInput).add(objectInput).add(objectInput).add(objectInput)
}, benchOptions)
})
})
class Vector2DArray {
#x: number
#y: number
get x() {
return this.#x
}
get y() {
return this.#y
}
constructor(x: number, y: number) {
this.#x = x
this.#y = y
}
add([x, y]: [number, number]): this {
this.#x += x
this.#y += y
return this
}
}
class Vector2DObject {
#x: number
#y: number
get x() {
return this.#x
}
get y() {
return this.#y
}
constructor(x: number, y: number) {
this.#x = x
this.#y = y
}
add({ x, y }: { x: number, y: number }): this {
this.#x += x
this.#y += y
return this
}
}
class Vector2DInstance {
#x: number
#y: number
get x() {
return this.#x
}
get y() {
return this.#y
}
constructor(x: number, y: number) {
this.#x = x
this.#y = y
}
add({ x, y }: Vector2DInstance): this {
this.#x += x
this.#y += y
return this
}
}
class Vector2DObjectCachedMap {
#x: number
#y: number
private cache: Map<string, Vector2DObjectCachedMap>
get x() { return this.#x }
get y() { return this.#y }
constructor(x: number, y: number) {
this.#x = x
this.#y = y
this.cache = new Map()
}
add(input: { x: number, y: number }): Vector2DObjectCachedMap {
const key = `${input.x},${input.y}`
let result = this.cache.get(key)
if (result) return result
result = new Vector2DObjectCachedMap(this.#x + input.x, this.#y + input.y)
this.cache.set(key, result)
return result
}
}
// New Vector2DObjectCachedWeakMap implementation
class Vector2DObjectCachedWeakMap {
#x: number
#y: number
private weakCache: WeakMap<object, Vector2DObjectCachedWeakMap>
get x() { return this.#x }
get y() { return this.#y }
constructor(x: number, y: number) {
this.#x = x
this.#y = y
this.weakCache = new WeakMap()
}
add(input: { x: number, y: number }): Vector2DObjectCachedWeakMap {
let result = this.weakCache.get(input)
if (result) return result
result = new Vector2DObjectCachedWeakMap(this.#x + input.x, this.#y + input.y)
this.weakCache.set(input, result)
return result
}
}
/*
BENCH Summary
vector2DObject - packages/vector-2d/src/__tests__/vector-2d.bench.ts > vector2D operations with various inputs 1000 > input: 'Small integers'
1.00x faster than vector2DInstance
1.20x faster than vector2DObjectCachedWeakMap
1.23x faster than vector2DArray
1.84x faster than vector2DObjectCachedMap
vector2DObjectCachedWeakMap - packages/vector-2d/src/__tests__/vector-2d.bench.ts > vector2D operations with various inputs 1000 > input: 'Large integers'
1.36x faster than vector2DArray
1.46x faster than vector2DObject
1.54x faster than vector2DInstance
7.26x faster than vector2DObjectCachedMap
vector2DObjectCachedWeakMap - packages/vector-2d/src/__tests__/vector-2d.bench.ts > vector2D operations with various inputs 1000 > input: 'Floating point'
1.21x faster than vector2DInstance
1.37x faster than vector2DObject
1.48x faster than vector2DArray
6.57x faster than vector2DObjectCachedMap
vector2DObject - packages/vector-2d/src/__tests__/vector-2d.bench.ts > vector2D operations with various inputs 1000 > input: 'Very small floating point'
1.09x faster than vector2DObjectCachedWeakMap
1.23x faster than vector2DInstance
1.62x faster than vector2DArray
11.37x faster than vector2DObjectCachedMap
vector2DObject - packages/vector-2d/src/__tests__/vector-2d.bench.ts > vector2D operations with various inputs 1000 > input: 'Mixed values'
1.07x faster than vector2DInstance
1.07x faster than vector2DObjectCachedWeakMap
1.29x faster than vector2DArray
3.07x faster than vector2DObjectCachedMap
vector2DObject - packages/vector-2d/src/__tests__/vector-2d.bench.ts > vector2D operations with various inputs 1000 > input: 'Zero values'
1.17x faster than vector2DInstance
1.30x faster than vector2DObjectCachedWeakMap
1.38x faster than vector2DArray
3.29x faster than vector2DObjectCachedMap
vector2DObject - packages/vector-2d/src/__tests__/vector-2d.bench.ts > vector2D operations with various inputs 1000 > input: 'Negative values'
1.12x faster than vector2DInstance
1.21x faster than vector2DArray
1.24x faster than vector2DObjectCachedWeakMap
3.19x faster than vector2DObjectCachedMap
vector2DObject - packages/vector-2d/src/__tests__/vector-2d.bench.ts > vector2D operations with various inputs 1000 > chaining many small additions
2.04x faster than vector2DObjectCachedWeakMap
2.21x faster than vector2DInstance
3.27x faster than vector2DArray
5.46x faster than vector2DObjectCached
vector2DObject - packages/vector-2d/src/__tests__/vector-2d.bench.ts > vector2D operations with various inputs +0 > input: 'Small integers'
1.16x faster than vector2DInstance
1.41x faster than vector2DObjectCachedWeakMap
1.41x faster than vector2DArray
3.59x faster than vector2DObjectCachedMap
vector2DObjectCachedWeakMap - packages/vector-2d/src/__tests__/vector-2d.bench.ts > vector2D operations with various inputs +0 > input: 'Large integers'
1.15x faster than vector2DInstance
1.34x faster than vector2DObject
2.33x faster than vector2DArray
6.51x faster than vector2DObjectCachedMap
vector2DObjectCachedWeakMap - packages/vector-2d/src/__tests__/vector-2d.bench.ts > vector2D operations with various inputs +0 > input: 'Floating point'
1.09x faster than vector2DInstance
1.31x faster than vector2DArray
1.34x faster than vector2DObject
5.99x faster than vector2DObjectCachedMap
vector2DObject - packages/vector-2d/src/__tests__/vector-2d.bench.ts > vector2D operations with various inputs +0 > input: 'Very small floating point'
1.01x faster than vector2DObjectCachedWeakMap
1.52x faster than vector2DInstance
1.63x faster than vector2DArray
9.66x faster than vector2DObjectCachedMap
vector2DObjectCachedWeakMap - packages/vector-2d/src/__tests__/vector-2d.bench.ts > vector2D operations with various inputs +0 > input: 'Mixed values'
1.00x faster than vector2DInstance
1.09x faster than vector2DObject
1.24x faster than vector2DArray
3.09x faster than vector2DObjectCachedMap
vector2DInstance - packages/vector-2d/src/__tests__/vector-2d.bench.ts > vector2D operations with various inputs +0 > input: 'Zero values'
1.02x faster than vector2DObject
1.27x faster than vector2DArray
1.27x faster than vector2DObjectCachedWeakMap
3.06x faster than vector2DObjectCachedMap
vector2DObject - packages/vector-2d/src/__tests__/vector-2d.bench.ts > vector2D operations with various inputs +0 > input: 'Negative values'
1.06x faster than vector2DInstance
1.28x faster than vector2DObjectCachedWeakMap
1.55x faster than vector2DArray
3.12x faster than vector2DObjectCachedMap
vector2DObject - packages/vector-2d/src/__tests__/vector-2d.bench.ts > vector2D operations with various inputs +0 > chaining many small additions
1.91x faster than vector2DObjectCachedWeakMap
2.09x faster than vector2DInstance
2.86x faster than vector2DArray
5.67x faster than vector2DObjectCached
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment