Add a Float32Array variant
Some test numbers [main] [info] 5399 embeddings 29 million ops 11 seconds normal [main] [info] 5399 embeddings 29 million ops 8 seconds float32 [main] [info] 5399 embeddings 29 million ops 8 seconds float32 with loop unrolling [main] [info] 5399 embeddings 29 million ops 4 seconds simsimd [rndr] [info] 5399 embeddings 29 million ops 12 seconds normal [rndr] [info] 5399 embeddings 29 million ops 7 seconds float32 [rndr] [info] 5399 embeddings 29 million ops 7 seconds float32 with loop unrolling [rndr] [info] 5399 embeddings 29 million ops 7 seconds wasm simd
This commit is contained in:
@@ -11,6 +11,19 @@ export const clamp = (value: number, min: number, max: number) =>
|
||||
* the two given vectors.
|
||||
*
|
||||
* Precondition: The two vectors must be of the same length.
|
||||
*
|
||||
* [Note: Dot product performance]
|
||||
*
|
||||
* In theory, WASM SIMD instructions should give us a huge boost for computing
|
||||
* dot products. In practice, we can get to roughly around the same performance
|
||||
* by using Float32Arrays instead of number[], and letting the JS JIT do the
|
||||
* optimizations for us. (This assertion was made on Chrome on macOS on Sep
|
||||
* 2023, and may not hold in the future).
|
||||
*
|
||||
* We can get an extra 2x speedup over this by using some library that directly
|
||||
* uses the SIMD intrinsics provided by the architecture instead of limiting
|
||||
* itself to the WASM's set. But that requires bundling native code, so as a
|
||||
* tradeoff to avoid complexity we live with leaving that 1x on the table.
|
||||
*/
|
||||
export const dotProduct = (v1: number[], v2: number[]) => {
|
||||
if (v1.length != v2.length)
|
||||
@@ -21,6 +34,16 @@ export const dotProduct = (v1: number[], v2: number[]) => {
|
||||
return d;
|
||||
};
|
||||
|
||||
export const dotProductF32 = (v1: Float32Array, v2: Float32Array) => {
|
||||
if (v1.length != v2.length)
|
||||
throw new Error(`Length mismatch ${v1.length} ${v2.length}`);
|
||||
let d = 0;
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
for (let i = 0; i < v1.length; i++) d += v1[i]! * v2[i]!;
|
||||
return d;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Return the L2-norm ("magnitude") of the given vector.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user