如果您想要更快的速度,请将 id 处理为整数,而不是数组,并使用 & 和 | 进行一些更改 操作:
counts = {};
var a = [1,0,1,0,0,3];
for(var i=0; i<a.length; i++ ){
var c = counts[a[i]] || 0 ;
counts[a[i]]= c+1 ;
}
console.log(counts); // { 0: 3, 1: 2, 3: 1 }
设置第 k 位:
id |= 1 << k;
清除第 k 位:
id &= !(1 << k);
交换第 k 位:
id ^= (1 << k);
读取第 k 位:
bitK = (id >> k ) & 1;
因此,您可能会编写小函数来执行这些操作,它们有 99% 的机会被 javascript 引擎内联,这将比数组处理 + parseInt 快得多。
您甚至可以直接编写此代码。也许在某些情况下,您将能够缓存 1 << k,但无论如何,移位指令的成本非常低。
另一个优点是您可以在一条指令中处理多个测试,例如:
var setRequiredMask = ( 1<<3 | 1<<5 ) ; // to test if bits 3 and 5 set
var clearRequiredMask = ( 1<<2 | 1 <<4 ) ; // to test if bit 2 and 4 cleared
var someRequiredMask = ( 1<<0 | 1 <<6 ) ; // to test if either bit 0 or bit 6 to be set
var satisfyConditions = ((id & setRequiredMask) == setRequiredMask) &&
((id & !clearRequiredMask) ==0 ) &&
(id & someRequiredMask) ;
在这里,我们将 7 次内存访问换成完全相同数量的布尔运算。
如果在循环中使用这个测试来过滤一个数组,速度增益是巨大的。
以同样的方式,您可以在一条指令中设置/清除/交换多个位,测试一个条件集是否包含在另一个条件集中,测试它们是否正交,......所有这些都以非常快的方式进行。
唯一的限制是您可以使用此方法处理不超过 32 种可能性。
然后,您可以将 id 存储在类型化数组中,具体取决于可能性的最大数量,仅使用 Int8Array 或 Int32Array,但与 [] 相比,我不确定性能增益是否会那么有趣。
句法 :
var arr = new Int8Array( _length_ );
或者
var arr = new Int32Array( _length_ );