我将在 Javascript 中存储大量字节值(最有可能超过100万)。如果我使用一个普通的数组和普通的数字,这将需要8 MB,因为数字是以 IEEE 双精度存储的,但是如果我可以以字节的形式存储它,它将只有1 MB。
出于显而易见的原因,我不想浪费那么多空间。有没有办法将字节存储为字节而不是双精度的?浏览器兼容性对我来说不是问题,只要它能在 Chrome 中工作。这是在 HTML5中,如果这有什么区别的话。
您可以将数据存储在固定大小的字符串数组中。访问字符串数组中的任何特定字符并将该字符视为字节应该是有效的。
看到您想要支持的操作(可能以接口的形式表示) ,以使问题更具体,将是一件有趣的事情。
通过使用 类型化数组,您可以存储 这些类型的数组:
Int8Array
Uint8Array
Uint8ClampedArray
Int16Array
Uint16Array
Int32Array
Uint32Array
Float32Array
Float64Array
BigInt64Array
BigUint64Array
var array = new Uint8Array(100); array[42] = 10; console.log(array[42]);
var array = new Uint8Array(100); array[10] = 256; array[10] === 0 // true
我在 firefox 和 chrome 中验证过,它实际上是一个字节数组:
var array = new Uint8Array(1024*1024*50); // allocates 50MBytes
我想要这个问题有一个更精确和有用的答案。下面是真正的答案(如果您想要一个特定的 字节数组,可以相应地进行调整; 很明显,数学会偏离 8 bits : 1 byte的一个因子) :
8 bits : 1 byte
class BitArray { constructor(bits = 0) { this.uints = new Uint32Array(~~(bits / 32)); } getBit(bit) { return (this.uints[~~(bit / 32)] & (1 << (bit % 32))) != 0 ? 1 : 0; } assignBit(bit, value) { if (value) { this.uints[~~(bit / 32)] |= (1 << (bit % 32)); } else { this.uints[~~(bit / 32)] &= ~(1 << (bit % 32)); } } get size() { return this.uints.length * 32; } static bitsToUints(bits) { return ~~(bits / 32); } }
用法:
let bits = new BitArray(500); for (let uint = 0; uint < bits.uints.length; ++uint) { bits.uints[uint] = 457345834; } for (let bit = 0; bit < 50; ++bit) { bits.assignBit(bit, 1); } str = ''; for (let bit = bits.size - 1; bit >= 0; --bit) { str += bits.getBit(bit); } str;
产出:
"00011011010000101000101100101010 00011011010000101000101100101010 00011011010000101000101100101010 00011011010000101000101100101010 00011011010000101000101100101010 00011011010000101000101100101010 00011011010000101000101100101010 00011011010000101000101100101010 00011011010000101000101100101010 00011011010000101000101100101010 00011011010000101000101100101010 00011011010000101000101100101010 00011011010000101000101100101010 00011011010000111111111111111111 11111111111111111111111111111111"
注意: 这个类对于分配位(即每1000万次分配约2s)来说真的很慢。 如果它是作为一个全局变量创建的,至少在 Linux 上的 Firefox 76.0控制台中是这样... ... 另一方面,如果是作为一个变量创建的(即 let bits = new BitArray(1e7);) ,那么是 极快的速度(即每1000万次分配约300ms) !
let bits = new BitArray(1e7);
欲了解更多信息,请点击这里:
注意,我使用 Uint32Array 是因为没有办法直接使用位/字节数组(您可以直接与之交互) 还有,因为即使有 BigUint64Array,JS 也只支持32位:
按位运算符将其操作数视为32位的序列 ... 所有按位运算符的操作数都被转换成... 32位整数
按位运算符将其操作数视为32位的序列
...
所有按位运算符的操作数都被转换成... 32位整数