@leolee9086/string-metrics-dice
Version:
Sørensen-Dice 系数算法库
132 lines (122 loc) • 4.52 kB
JavaScript
/**
* 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;