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:
Manav Rathi
2024-09-03 13:28:44 +05:30
parent 86d3067713
commit 9a68c48456

View File

@@ -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.
*