UNPKG

@leolee9086/string-metrics-dice

Version:
132 lines (122 loc) 4.52 kB
/** * Rust WASM 高性能 Sørensen-Dice 系数算法包装器(自动适配Node与浏览器) * * 提供与主API一致的接口,自动处理WASM模块的加载和初始化 */ let wasmModule = null; let isInitialized = false; function isNode() { return typeof process !== 'undefined' && process.versions && process.versions.node; } /** * 初始化WASM模块 * @returns {Promise<void>} */ export async function init() { if (isInitialized) return; try { if (isNode()) { // Node.js环境,使用require加载CJS const wasm = await import('./node/string_metrics_dice_wasm.js'); wasmModule = wasm; } else { // 浏览器/ESM环境 const wasm = await import('./web/string_metrics_dice_wasm.js'); wasmModule = wasm; } isInitialized = true; console.log('WASM模块初始化成功'); } catch (e) { console.error('WASM模块初始化失败:', e); throw new Error('WASM模块加载失败,请确保已构建WASM文件'); } } /** * 检查WASM模块是否已初始化 * @returns {boolean} */ export function isReady() { return isInitialized && wasmModule !== null; } /** * 转换JavaScript选项为Rust选项 * @param {import('../schema.js').DiceCoefficientOptions} jsOptions - JavaScript选项 * @returns {Object} Rust选项对象 */ function convertOptions(jsOptions = {}) { if (!wasmModule || typeof wasmModule.DiceOptions !== 'function') return undefined; if (Object.keys(jsOptions).length === 0) return undefined; return wasmModule.DiceOptions.new( jsOptions.nGramSize || 2 ); } /** * 计算Sørensen-Dice系数(WASM版本) * * @param {string} str1 - 第一个字符串 * @param {string} str2 - 第二个字符串 * @param {import('../schema.js').DiceCoefficientOptions} options - 计算选项 * @returns {number} Dice系数,范围[0,1] */ export function computeDiceCoefficient(str1, str2, options = {}) { if (!isReady()) throw new Error('WASM模块未初始化,请先调用init()'); if (typeof str1 !== 'string' || typeof str2 !== 'string') throw new TypeError('输入必须是字符串'); const rustOptions = convertOptions(options); return wasmModule.compute_dice_coefficient(str1, str2, rustOptions); } /** * 计算Dice距离(1 - Dice系数)(WASM版本) * * @param {string} str1 - 第一个字符串 * @param {string} str2 - 第二个字符串 * @param {import('../schema.js').DiceCoefficientOptions} options - 计算选项 * @returns {number} Dice距离,范围[0,1] */ export function computeDiceDistance(str1, str2, options = {}) { if (!isReady()) throw new Error('WASM模块未初始化,请先调用init()'); if (typeof str1 !== 'string' || typeof str2 !== 'string') throw new TypeError('输入必须是字符串'); const rustOptions = convertOptions(options); return wasmModule.compute_dice_distance(str1, str2, rustOptions); } /** * 获取WASM算法信息 * @returns {import('../schema.js').AlgorithmMetadata} 算法元数据 */ export function getAlgorithmInfo() { if (!isReady()) throw new Error('WASM模块未初始化,请先调用init()'); // 兼容wasm-bindgen返回的Map/JsValue等 const info = wasmModule.get_algorithm_info(); if (info && typeof info === 'object' && typeof info.entries === 'function') { // Map转对象 return Object.fromEntries(info.entries()); } return info; } /** * 性能测试函数 * @param {string} str1 - 第一个字符串 * @param {string} str2 - 第二个字符串 * @param {number} iterations - 迭代次数 * @returns {Object} 性能测试结果 */ export function benchmark(str1, str2, iterations = 100000) { if (!isReady()) throw new Error('WASM模块未初始化,请先调用init()'); const startTime = (typeof performance !== 'undefined' ? performance : Date).now(); for (let i = 0; i < iterations; i++) { computeDiceCoefficient(str1, str2); } const endTime = (typeof performance !== 'undefined' ? performance : Date).now(); const totalTime = endTime - startTime; const opsPerSecond = (iterations / totalTime) * 1000; return { iterations, totalTime: totalTime.toFixed(2) + 'ms', opsPerSecond: Math.round(opsPerSecond).toLocaleString(), averageTime: (totalTime / iterations).toFixed(6) + 'ms' }; } // 向后兼容的中文函数名 export const 计算Dice系数 = computeDiceCoefficient; export const 计算Dice距离 = computeDiceDistance; export const 获取算法信息 = getAlgorithmInfo; export const 性能测试 = benchmark;