1.首先想到的就是通過與運(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;
}
這個方法是java提供的一個計算的方式。
那么問題來了。這樣計算是可以的,也很快。但是我想更快怎么?
2.通過緩存的方式來出來
為了更快的速度,那我們可以犧牲一部分存儲空間。就是最典型的 空間換時間
我們可以生成一個key-value的接口對應(yīng)起來
1 -> 1 -> 1
2 -> 10 -> 1
3 -> 11 -> 2
4 -> 100 -> 1
5 -> 101 -> 2
6 -> 110 -> 2
7 -> 111 -> 3
8 -> 1000 -> 1
我們稍微計算一下啊
int 有4字節(jié),32位范圍
-2147483648—2147483647(2^31-1)
我們只要計算一下大概有多少
先算正整數(shù)。
我們只要計算一下大概有多少
我們估算位2^32這些數(shù)據(jù)
共占有2^34個字節(jié)
1個int 占用2^2個字節(jié)
1Gb = 2^30 B
大概約等于4G的空間這是key,要是K-V的方式存放,遠(yuǎn)遠(yuǎn)大于額8G
有沒有方式優(yōu)化存儲方式?
1.對數(shù)據(jù)進(jìn)行降維打擊
我們可以吧K-V的方式轉(zhuǎn)換成二維平面,對k-v求解向量。我們就得到的了一個點。這樣存的數(shù)據(jù)遠(yuǎn)遠(yuǎn)小于4G
。甚至也就只有1G左右。但是不夠我還想更小。
2.考慮拆分法
int :4個字節(jié) 32位
可以拆成 16位 + 16位
拿的key的存放應(yīng)該是2^5MB
那么肯定有小伙伴會問如果我們分成
8位 + 8位 + 8位 + 8位
是不是更小。
我們?nèi)绾闻袛嗄莻€一更好?是16位還是8位?
這就涉及到CPU的寄存器。
最好的方式就是分的位數(shù)和寄存器的位數(shù)一樣大。這樣速度是最快的。