import { describe, expect, it } from '@jest/globals'; import { bGcdPrs } from '../../../src/gcd/bigint/b-gcd-prs.js'; import { bGcdModular } from '../../../src/gcd/bigint/b-gcd-modular.js'; import { bIsRationalMultipleOf } from '../../../src/basic/bigint/b-is-rational-multiple-of.js'; import { bMultiply } from '../../../src/basic/bigint/b-multiply.js'; import { bDifferentiate } from '../../../src/calculus/bigint/b-differentiate.js'; import { bFromRoots } from '../../../src/roots/from-roots/bigint/b-from-roots.js'; import { squares } from 'squares-rng'; type BenchCase = { name: string; a: bigint[]; b: bigint[]; repeats: number; }; function randomSigned64(seed: number): bigint { const hi = BigInt(squares(seed) >>> 0); const lo = BigInt(squares(seed + 1) >>> 0); const x = (hi << 32n) + lo; // Convert to signed 64-bit range [-2^63, 2^63-1]. const s = x >= (1n << 63n) ? x - (1n << 64n) : x; return s === 0n ? 1n : s; } function makeRandomPoly( degree: number, seedStart: number): bigint[] { const p = new Array(degree + 1); for (let i=0; i<=degree; i++) { p[i] = randomSigned64(seedStart + 2*i); } // Ensure leading coefficient is nonzero. if (p[0] === 0n) { p[0] = 1n; } return p; } function makeDerivativeCaseFromRoots( name: string, roots: bigint[], repeats: number): BenchCase { const p = bFromRoots(roots); const dp = bDifferentiate(p); return { name, a: p, b: dp, repeats }; } function makeRepeatedRootWorkload( distinctRootCount: number, scale: bigint, repeats: number): BenchCase { const roots: bigint[] = []; for (let i=0; i = []; for (const tc of cases) { // Sanity: both implementations should produce equivalent GCDs. const gcdPrs = bGcdPrs(tc.a, tc.b); const gcdMod = bGcdModular(tc.a, tc.b); expect(bIsRationalMultipleOf(gcdPrs, gcdMod)).toEqual(true); expect(bIsRationalMultipleOf(gcdMod, gcdPrs)).toEqual(true); // Warmup bGcdPrs(tc.a, tc.b); bGcdModular(tc.a, tc.b); const tPrsStart = performance.now(); for (let r=0; r acc + r.prsMs, 0); const totalMod = results.reduce((acc, r) => acc + r.modMs, 0); console.log('--- bigint gcd benchmark ---'); for (const r of results) { console.log( `${r.name} | repeats=${r.repeats} | prs=${r.prsMs.toFixed(2)}ms | modular=${r.modMs.toFixed(2)}ms | mod/prs=${r.ratio.toFixed(2)}x` ); } console.log('--- totals ---'); console.log(`cases: ${results.length}`); console.log(`bGcdPrs total ms: ${totalPrs.toFixed(2)}`); console.log(`bGcdModular total ms: ${totalMod.toFixed(2)}`); console.log(`modular/prs: ${(totalMod / totalPrs).toFixed(2)}x`); }); });