1.首先想到的就是通過(guò)與運(yùn)算獲取
public static int bitCount(long i) {
// HD, Figure 5-14
i = i - ((i >>> 1) & 0x5555555555555555L);
i = (i & 0x3333333333333333L) + ((i >>> 2) & 0x3333333333333333L);
i = (i + (i >>> 4)) & 0x0f0f0f0f0f0f0f0fL;
i = i + (i >>> 8);
i = i + (i >>> 16);
i = i + (i >>> 32);
return (int)i & 0x7f;
}
這個(gè)方法是java提供的一個(gè)計(jì)算的方式假夺。
那么問(wèn)題來(lái)了。這樣計(jì)算是可以的斋攀,也很快已卷。但是我想更快怎么?
2.通過(guò)緩存的方式來(lái)出來(lái)
為了更快的速度淳蔼,那我們可以犧牲一部分存儲(chǔ)空間侧蘸。就是最典型的 空間換時(shí)間
我們可以生成一個(gè)key-value的接口對(duì)應(yīng)起來(lái)
1 -> 1 -> 1
2 -> 10 -> 1
3 -> 11 -> 2
4 -> 100 -> 1
5 -> 101 -> 2
6 -> 110 -> 2
7 -> 111 -> 3
8 -> 1000 -> 1
我們稍微計(jì)算一下啊
int 有4字節(jié),32位范圍
-2147483648—2147483647(2^31-1)
我們只要計(jì)算一下大概有多少
先算正整數(shù)鹉梨。
我們只要計(jì)算一下大概有多少
我們估算位2^32這些數(shù)據(jù)
共占有2^34個(gè)字節(jié)
1個(gè)int 占用2^2個(gè)字節(jié)
1Gb = 2^30 B
大概約等于4G的空間這是key讳癌,要是K-V的方式存放,遠(yuǎn)遠(yuǎn)大于額8G
有沒(méi)有方式優(yōu)化存儲(chǔ)方式存皂?
1.對(duì)數(shù)據(jù)進(jìn)行降維打擊
我們可以吧K-V的方式轉(zhuǎn)換成二維平面晌坤,對(duì)k-v求解向量。我們就得到的了一個(gè)點(diǎn)旦袋。這樣存的數(shù)據(jù)遠(yuǎn)遠(yuǎn)小于4G
骤菠。甚至也就只有1G左右。但是不夠我還想更小疤孕。
2.考慮拆分法
int :4個(gè)字節(jié) 32位
可以拆成 16位 + 16位
拿的key的存放應(yīng)該是2^5MB
那么肯定有小伙伴會(huì)問(wèn)如果我們分成
8位 + 8位 + 8位 + 8位
是不是更小娩怎。
我們?nèi)绾闻袛嗄莻€(gè)一更好?是16位還是8位胰柑?
這就涉及到CPU的寄存器截亦。
最好的方式就是分的位數(shù)和寄存器的位數(shù)一樣大爬泥。這樣速度是最快的。