汉明重量(Hamming Weight)以及 redis的bitcout底层

Hamming Weight,即汉明重量,指的是一个位数组中非0二进制位的数量。


解决问题:

有100M的二进制数据,算出里面有多少个1 ?(1MB = 1,000,000 Byte = 8,000,000 bit)


1、遍历法:

遍历 8 亿次,右移比较 8 亿次。

public int hammingWeight(int n) {
  int res = 0;
  while(n!=0) {
    res+= (n & 0x1);
    n >>>=1;
  }
  return res;
}
2、 查表法:(空间换时间)
key value(值为1的数量)
0000 0000 0
0000 0001 1
1111 1111 8

遍历 1 亿次

空间: 比如java的map<String,integer> 

上述键长为 8 位,那么 2 ^ 8 = 256 ,

String 所需要字节(一个英文字母或者数字占1个字节): 256 * 8 = 2048 byte

Integer 所需要字节 ( 0,1,2,3,4,5,6,7,8)(一个Integer对象粗略统计 3* 4 = 12字节) 9 * 12 = 108 byte

算上map对象总共差不多2500 byte. 



若键的长度持续增加,那么比如16位:

2500 * 2 ^ ( 16 / 8 ) =  2500 * 256 = 625k byte



若是 32位:

2500 * 2 ^ ( 32 / 8 ) = 2500 * ( 2 ^ 24) = 40,000 M byte = 40G



瓶颈 :

1、 内存

2、cpu缓存 :查表之后,会有部分数据打到cpu缓存里面,方便下次使用,但是表格越大,缓存不命中的情况就越高,那么缓存就会不断换入换出,影响性能

3、汉明重量 :variable-precision SWAR 算法

第一步:
  计算出来的值i的二进制可以按每2个二进制位为一组进行分组,各组的十进制表示的就是该组的汉明重量。
第二步:
  计算出来的值i的二进制可以按每4个二进制位为一组进行分组,各组的十进制表示的就是该组的汉明重量。
第三步:
  计算出来的值i的二进制可以按每8个二进制位为一组进行分组,各组的十进制表示的就是该组的汉明重量。
第四步:
  i * (0x01010101)计算出汉明重量并记录在二进制的高八位,>>24语句则通过右移运算,将汉明重量移到最低八位,最后二

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值