我将在Javascript中存储一个大型的字节值数组(很可能超过一百万)。如果我使用一个普通的数字数组,那将需要8 MB,因为数字是以IEEE双数的形式存储的,但如果我可以以字节的形式存储,那就只有1 MB。
我想避免浪费那么多空间,原因很明显。有没有一种方法可以将字节存储为字节而不是双字节?浏览器兼容性对我来说不是问题,只要能在Chrome浏览器中使用就可以了。这是在HTML5中,如果这有区别的话。
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
):
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"
注意:这个类的速度真的很慢,比如说分配比特(即每一千万次分配约2s)。 这个类的速度真的很慢,例如分配比特(即每一千万次分配约2s)。如果 它被创建为一个全局变量,至少在Linux上的Firefox 76.0控制台中是这样的...... 如果另一方面,它被创建为一个变量(即 let bits = new BitArray(1e7);
), 然后 它 神速 (即每1000万次作业约300ms)!
更多信息,请看这里。
请注意,我使用了Uint32Array,因为没有办法直接拥有一个比特字节数组(可以直接与之交互)。和 因为即使有 BigUint64Array
,JS只支持32位。
位元运算符将其操作数视为32位的序列。
...
所有位运算符的操作数都被转换为...32位整数。