如何在JavaScript TypedArray中存储和读取二进制矩阵?
优化现有TypedArray实现(推荐方案)
无需转二进制的按位运算实现
你当前将整数转为二进制字符串再做运算的操作完全冗余,按位运算可以直接在TypedArray的字节维度逐位对齐执行:
- 假设你要对第i行和第j行做按位与/或/异或操作,先分别拿到两行对应的Uint8切片,逐字节执行运算即可:
// subarray是原缓冲区的引用,不会发生内存拷贝,比slice快数倍 const rowA = uint8Buffer.subarray(i * rowLength, (i+1)*rowLength); const rowB = uint8Buffer.subarray(j * rowLength, (j+1)*rowLength); const result = new Uint8Array(rowLength); for (let k = 0; k < rowLength; k++) { result[k] = rowA[k] & rowB[k]; // 替换为|、^即可实现或、异或运算 } - 如果需要读取某一行的单个比特位,也不需要转字符串,直接计算偏移即可:
// 读取第i行第col位的值,返回0或1 function getBit(i, col) { const byteIdx = Math.floor(col / 8) + i * rowLength; const bitOffset = 7 - (col % 8); // 可按需调整大小端顺序 return (uint8Buffer[byteIdx] >> bitOffset) & 1; }
额外优化点
- 不需要提前把列数补到8的倍数,只需要存储原始列数
originalCol,运算和读取时跳过最后一个字节的补位部分即可,能进一步节省存储空间 - 如果场景允许对齐到32位,替换Uint8Array为Uint32Array,循环次数减少为原来的1/4,运算速度会有3-4倍的提升
不用TypedArray的实现方案
如果你的运行场景不支持TypedArray,可以用BigInt实现,代码更简洁,兼容性更好:
- 每一行直接存储为一个BigInt类型值,n位的二进制行直接对应一个BigInt,不需要补位到8的倍数
- 按位运算直接调用JS原生BigInt的&/|/^运算符,语法简洁运算效率高
- 示例代码:
const matrix = []; // 写入一行二进制数组bits(元素为0或1) function addRow(bits) { let row = 0n; for (const bit of bits) { row = (row << 1n) | BigInt(bit); } matrix.push(row); } // 直接对两行执行按位与运算 const andResult = matrix[i] & matrix[j];
该方案的缺点是列数超过10万位时,BigInt的运算性能会略低于TypedArray逐字节运算的方案。
内容的提问来源于stack exchange,提问作者Dianne
相关产品推荐
相关产品推荐

