我将在Javascript中存储一个大型字节数组(很可能超过一百万个)。如果我使用普通数组和普通数字,则需要8 MB,因为数字以IEEE doubles的形式存储,但是如果我可以将其存储为字节,则仅需要1 MB。
出于明显的原因,我希望避免浪费那么多空间。是否有一种可以将字节存储为字节而不是doubles的方法?对于我来说,浏览器兼容性不是问题,只要它可以在Chrome中工作即可。如果这是在HTML5中,是否有区别呢?
我将在Javascript中存储一个大型字节数组(很可能超过一百万个)。如果我使用普通数组和普通数字,则需要8 MB,因为数字以IEEE doubles的形式存储,但是如果我可以将其存储为字节,则仅需要1 MB。
出于明显的原因,我希望避免浪费那么多空间。是否有一种可以将字节存储为字节而不是doubles的方法?对于我来说,浏览器兼容性不是问题,只要它可以在Chrome中工作即可。如果这是在HTML5中,是否有区别呢?
类型 | 取值范围 | 大小(字节) |
---|---|---|
Int8Array |
-128 到 127 | 1 |
Uint8Array |
0 到 255 | 1 |
Uint8ClampedArray |
0 到 255 | 1 |
Int16Array |
-32768 到 32767 | 2 |
Uint16Array |
0 到 65535 | 2 |
Int32Array |
-2147483648 到 2147483647 | 4 |
Uint32Array |
0 到 4294967295 | 4 |
Float32Array |
-3.4E38 到 3.4E38 | 4 |
Float64Array |
-1.8E308 到 1.8E308 | 8 |
BigInt64Array |
-2^63 到 2^63 - 1 | 8 |
BigUint64Array |
0 到 2^64 - 1 | 8 |
var array = new Uint8Array(100);
array[42] = 10;
console.log(array[42]);
Float32Array
将数组长度为800,000+元素的生成时间从2.4秒缩短至0.12秒,这真是神奇的差异! - Robbie Wxyzvar array = new Uint8Array(100);
array[10] = 256;
array[10] === 0 // true
我在Firefox和Chrome中验证过,确实是一组字节:
var array = new Uint8Array(1024*1024*50); // allocates 50MBytes
8位:1字节
的因素):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"
注意:如果这个类作为全局变量创建,例如在Linux上的Firefox 76.0控制台中分配位(即每1000万次分配需要大约2秒),那么速度会非常慢...但是,如果将其作为变量创建(即let bits = new BitArray(1e7);
),那么它就会非常快(即每1000万次分配大约300毫秒)!
更多信息,请参见此处:
请注意,我使用Uint32Array是因为没有直接拥有可直接交互的位/字节数组(且仅支持32位)的方法,同时即使有BigUint64Array,JS也仅支持32位。
位运算符将它们的操作数视为32位序列。...所有位运算符的操作数都被转换为32位整数。
Int8Array
;如果你不需要字节有符号,那么类型为Uint8Array
。 - HoLyVieR