@sschepis/resolang
Version:
ResoLang - Core quantum resonance computation library for browser and Node.js
450 lines (380 loc) • 10.5 kB
text/typescript
/**
* Performance optimizations for hot paths
* Provides optimized implementations for frequently used operations
*/
import { Prime } from "../types";
import { sha256 } from "./crypto";
/**
* Fast modular exponentiation using binary method
* Optimized for crypto operations
*/
export function fastModExp(base: u64, exp: u64, mod: u64): u64 {
if (mod == 1) return 0;
let result: u64 = 1;
base = base % mod;
while (exp > 0) {
// If exp is odd, multiply base with result
if (exp & 1) {
result = (result * base) % mod;
}
// Square base and halve exp
exp = exp >> 1;
base = (base * base) % mod;
}
return result;
}
/**
* Fast primality test using Miller-Rabin
* Optimized for small primes (< 2^32)
*/
export function fastIsPrime(n: u32): bool {
if (n <= 1) return false;
if (n <= 3) return true;
if ((n & 1) == 0 || n % 3 == 0) return false;
// Check small primes
if (n < 9) return true;
if (n % 5 == 0 || n % 7 == 0) return false;
if (n < 121) return true; // 11 * 11
// Miller-Rabin test with optimal witnesses for 32-bit integers
const witnesses: u32[] = [2, 7, 61];
// Write n-1 as d * 2^r
let d = n - 1;
let r = 0;
while ((d & 1) == 0) {
d >>= 1;
r++;
}
for (let i = 0; i < witnesses.length; i++) {
const a = witnesses[i];
if (a >= n) continue;
let x = u32(fastModExp(a, d, n));
if (x == 1 || x == n - 1) continue;
let composite = true;
for (let j = 0; j < r - 1; j++) {
x = u32((u64(x) * u64(x)) % n);
if (x == n - 1) {
composite = false;
break;
}
}
if (composite) return false;
}
return true;
}
/**
* Fast GCD using binary algorithm
* More efficient than Euclidean for large numbers
*/
export function fastGCD(a: u64, b: u64): u64 {
if (a == 0) return b;
if (b == 0) return a;
// Find common factor of 2
let shift: u32 = 0;
while (((a | b) & 1) == 0) {
a >>= 1;
b >>= 1;
shift++;
}
// Remove factors of 2 from a
while ((a & 1) == 0) {
a >>= 1;
}
do {
// Remove factors of 2 from b
while ((b & 1) == 0) {
b >>= 1;
}
// Ensure a <= b
if (a > b) {
const temp = a;
a = b;
b = temp;
}
b = b - a;
} while (b != 0);
return a << shift;
}
/**
* Fast hash combining for multiple values
* Uses FNV-1a algorithm for speed
*/
export function fastHashCombine(values: Array<u64>): u64 {
const FNV_PRIME: u64 = 0x100000001b3;
const FNV_OFFSET: u64 = 0xcbf29ce484222325;
let hash = FNV_OFFSET;
for (let i = 0; i < values.length; i++) {
hash ^= values[i];
hash *= FNV_PRIME;
}
return hash;
}
/**
* Fast array sum with unrolled loop
*/
export function fastArraySum(arr: Float64Array): f64 {
const len = arr.length;
let sum = 0.0;
let i = 0;
// Unroll by 4
const unrollEnd = len - (len & 3);
for (; i < unrollEnd; i += 4) {
sum += arr[i] + arr[i + 1] + arr[i + 2] + arr[i + 3];
}
// Handle remaining elements
for (; i < len; i++) {
sum += arr[i];
}
return sum;
}
/**
* Fast dot product with loop unrolling
*/
export function fastDotProduct(a: Float64Array, b: Float64Array): f64 {
const len = a.length;
if (len != b.length) return 0.0;
let sum = 0.0;
let i = 0;
// Unroll by 4
const unrollEnd = len - (len & 3);
for (; i < unrollEnd; i += 4) {
sum += a[i] * b[i] + a[i + 1] * b[i + 1] +
a[i + 2] * b[i + 2] + a[i + 3] * b[i + 3];
}
// Handle remaining elements
for (; i < len; i++) {
sum += a[i] * b[i];
}
return sum;
}
/**
* Fast matrix multiplication for small matrices
* Optimized for 3x3 and 4x4 matrices common in quantum operations
*/
export function fastMatMul3x3(a: StaticArray<f64>, b: StaticArray<f64>, result: StaticArray<f64>): void {
// Assuming row-major order
const a00 = unchecked(a[0]), a01 = unchecked(a[1]), a02 = unchecked(a[2]);
const a10 = unchecked(a[3]), a11 = unchecked(a[4]), a12 = unchecked(a[5]);
const a20 = unchecked(a[6]), a21 = unchecked(a[7]), a22 = unchecked(a[8]);
const b00 = unchecked(b[0]), b01 = unchecked(b[1]), b02 = unchecked(b[2]);
const b10 = unchecked(b[3]), b11 = unchecked(b[4]), b12 = unchecked(b[5]);
const b20 = unchecked(b[6]), b21 = unchecked(b[7]), b22 = unchecked(b[8]);
unchecked(result[0] = a00 * b00 + a01 * b10 + a02 * b20);
unchecked(result[1] = a00 * b01 + a01 * b11 + a02 * b21);
unchecked(result[2] = a00 * b02 + a01 * b12 + a02 * b22);
unchecked(result[3] = a10 * b00 + a11 * b10 + a12 * b20);
unchecked(result[4] = a10 * b01 + a11 * b11 + a12 * b21);
unchecked(result[5] = a10 * b02 + a11 * b12 + a12 * b22);
unchecked(result[6] = a20 * b00 + a21 * b10 + a22 * b20);
unchecked(result[7] = a20 * b01 + a21 * b11 + a22 * b21);
unchecked(result[8] = a20 * b02 + a21 * b12 + a22 * b22);
}
/**
* Fast phase calculation using lookup table
*/
class PhaseCalculator {
private static sinTable: StaticArray<f64>;
private static cosTable: StaticArray<f64>;
private static readonly TABLE_SIZE: i32 = 4096;
private static initialized: bool = false;
static initialize(): void {
if (this.initialized) return;
this.sinTable = new StaticArray<f64>(this.TABLE_SIZE);
this.cosTable = new StaticArray<f64>(this.TABLE_SIZE);
const step = 2.0 * Math.PI / this.TABLE_SIZE;
for (let i = 0; i < this.TABLE_SIZE; i++) {
const angle = i * step;
unchecked(this.sinTable[i] = Math.sin(angle));
unchecked(this.cosTable[i] = Math.cos(angle));
}
this.initialized = true;
}
static fastSin(phase: f64): f64 {
if (!this.initialized) this.initialize();
// Normalize phase to [0, 2π)
phase = phase % (2.0 * Math.PI);
if (phase < 0) phase += 2.0 * Math.PI;
const index = i32((phase / (2.0 * Math.PI)) * this.TABLE_SIZE) & (this.TABLE_SIZE - 1);
return unchecked(this.sinTable[index]);
}
static fastCos(phase: f64): f64 {
if (!this.initialized) this.initialize();
// Normalize phase to [0, 2π)
phase = phase % (2.0 * Math.PI);
if (phase < 0) phase += 2.0 * Math.PI;
const index = i32((phase / (2.0 * Math.PI)) * this.TABLE_SIZE) & (this.TABLE_SIZE - 1);
return unchecked(this.cosTable[index]);
}
}
/**
* Fast complex number operations
*/
export class FastComplex {
constructor(
public real: f64,
public imag: f64
) {}
static fromPolar(magnitude: f64, phase: f64): FastComplex {
return new FastComplex(
magnitude * PhaseCalculator.fastCos(phase),
magnitude * PhaseCalculator.fastSin(phase)
);
}
magnitude(): f64 {
return Math.sqrt(this.real * this.real + this.imag * this.imag);
}
phase(): f64 {
return Math.atan2(this.imag, this.real);
}
add(other: FastComplex): FastComplex {
return new FastComplex(
this.real + other.real,
this.imag + other.imag
);
}
multiply(other: FastComplex): FastComplex {
return new FastComplex(
this.real * other.real - this.imag * other.imag,
this.real * other.imag + this.imag * other.real
);
}
conjugate(): FastComplex {
return new FastComplex(this.real, -this.imag);
}
}
/**
* Memory pool for frequently allocated objects
*/
export class ObjectPool<T> {
private pool: Array<T>;
private factory: () => T;
private reset: (obj: T) => void;
private maxSize: i32;
constructor(
factory: () => T,
reset: (obj: T) => void,
initialSize: i32 = 10,
maxSize: i32 = 100
) {
this.factory = factory;
this.reset = reset;
this.maxSize = maxSize;
this.pool = new Array<T>();
// Pre-allocate initial objects
for (let i = 0; i < initialSize; i++) {
this.pool.push(factory());
}
}
/**
* Gets an object from the pool
*/
acquire(): T {
if (this.pool.length > 0) {
return this.pool.pop();
}
return this.factory();
}
/**
* Returns an object to the pool
*/
release(obj: T): void {
if (this.pool.length < this.maxSize) {
this.reset(obj);
this.pool.push(obj);
}
}
}
/**
* Fast bit manipulation utilities
*/
export namespace BitOps {
/**
* Counts set bits (population count)
*/
export function popcount32(n: u32): i32 {
n = n - ((n >> 1) & 0x55555555);
n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
return ((((n + (n >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24);
}
/**
* Finds position of highest set bit
*/
export function highestBit32(n: u32): i32 {
if (n == 0) return -1;
return 31 - clz(n);
}
/**
* Finds position of lowest set bit
*/
export function lowestBit32(n: u32): i32 {
if (n == 0) return -1;
return ctz(n);
}
/**
* Checks if number is power of 2
*/
export function isPowerOf2(n: u32): bool {
return n > 0 && (n & (n - 1)) == 0;
}
/**
* Rounds up to next power of 2
*/
export function nextPowerOf2(n: u32): u32 {
if (n == 0) return 1;
n--;
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
return n + 1;
}
}
/**
* Cache-friendly array operations
*/
export namespace CacheOps {
/**
* Prefetch hint for read
*/
export function prefetchRead<T>(ptr: usize): void {
// AssemblyScript doesn't have prefetch intrinsics yet
// This is a placeholder for future optimization
}
/**
* Process array in cache-friendly blocks
*/
export function processInBlocks<T>(
arr: Array<T>,
blockSize: i32,
processor: (block: Array<T>, start: i32, end: i32) => void
): void {
const len = arr.length;
for (let i = 0; i < len; i += blockSize) {
const end = Math.min(i + blockSize, len);
processor(arr, i, end);
}
}
}
/**
* SIMD operations placeholder
* AssemblyScript SIMD support is still evolving
*/
export namespace SIMD {
/**
* Fast array addition using SIMD (when available)
*/
export function addArrays(a: Float64Array, b: Float64Array, result: Float64Array): void {
const len = a.length;
// For now, fallback to scalar operations
// TODO: Use v128 operations when stable
for (let i = 0; i < len; i++) {
unchecked(result[i] = a[i] + b[i]);
}
}
}
/**
* Initialize performance optimizations
*/
export function initializePerformance(): void {
PhaseCalculator.initialize();
}