Last active
August 13, 2024 07:38
-
-
Save nandordudas/1e0998c12f58e789cd8505e3cbeeb210 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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