我将在Javascript中存储大量字节值(最有可能超过一百万)。如果我使用普通数字的正常数组,那将需要8 MB,因为数字存储为IEEE双精度数,但如果我可以将其存储为字节数,则它将只有1 MB。
我想避免因为明显的原因而浪费那么多空间。有没有办法将字节存储为字节而不是双精度?浏览器兼容性对我来说不是问题,只要它适用于Chrome。这是在HTML5中,如果这有所不同。
答案 0 :(得分:50)
使用typed arrays,您可以存储these types的数组:
例如:
var array = new Uint8Array(100);
array[42] = 10;
alert(array[42]);
在行动here中查看。
答案 1 :(得分:6)
var array = new Uint8Array(100);
array[10] = 256;
array[10] === 0 // true
我在firefox和chrome中验证过,它实际上是一个字节数组:
var array = new Uint8Array(1024*1024*50); // allocates 50MBytes
答案 2 :(得分:2)
您可以将数据存储在一些大的固定大小的字符串数组中。访问该字符串数组中的任何特定字符应该是高效的,并将该字符视为一个字节。
看到你想要支持的操作(可能表达为一个界面)会使问题更加具体,这将是很有趣的。
答案 3 :(得分:-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"
注意:该课程的学习速度确实很慢,例如分配位(即每1千万个分配约2s)如果是作为全局变量创建的,至少在Linux上的Firefox 76.0控制台中... 如果,在另一个上手,它被创建为变量(即let bits = new BitArray(1e7);
),然后,它非常快(即,每1000万个作业大约300ms)!
有关更多信息,请参见此处:
请注意,我之所以使用Uint32Array,是因为无法直接拥有一个位/字节数组(可以直接与之交互)和,因为即使有一个BigUint64Array
,JS也仅支持32位:
按位运算符将其操作数视为32位序列
...
所有按位运算符的操作数都转换为... 32位整数