前幾天和同事討論設(shè)計(jì)的問題,關(guān)于用戶屬性的字段,表示這個用戶擁有的權(quán)限,比如對這個功能系統(tǒng)是否有5個權(quán)限,權(quán)限1有沒有,權(quán)限2有沒有......。 這種屬性具有一種特征,就是非真即否,只用兩個值就可以表示。這時我們可以想到計(jì)算機(jī)的芯片的基數(shù)單元就是有電還是沒有電,也就是和計(jì)算機(jī)里面有關(guān)的一切內(nèi)容都是用bit表示的。
同樣,我們對這類值的存儲,有很多人會偏向于這樣村,5個權(quán)限分別用5個數(shù)表示,如果都有權(quán)限,表示出來是,“1,2,3,4,5”。對,在Java中通過判斷這字符串中有沒有相應(yīng)的數(shù)值,就知道有沒有這個權(quán)限。比如“1,2,3,5” 這個字符串屬性的人就沒有4的權(quán)限。
在我看來,這種操作成本很高,需要大量的cpu進(jìn)行字符串的匹配工作。因?yàn)樵诨A(chǔ)類型中,String是最消耗內(nèi)存的。而計(jì)算機(jī)對于二進(jìn)制位操作最為擅長,我們可以把剛才題例中的5個權(quán)限這樣寫,11111,這個是個二進(jìn)制,換算成十進(jìn)制數(shù)為:63,通過&或|操作既能取出對應(yīng)操作位的值(可參考相關(guān)的符號操作)。
下面我們來看個例子:
publicstaticvoidtest() {
intflagInt= 432;
intloop= 1000000000;
StringstrFlag="1,2,4";
longtime1= System.currentTimeMillis();
while(loop> 0) {
intb=flagInt& 7;
loop--;
}
System.out.println("flag :"+(System.currentTimeMillis() -time1));
loop= 1000000000;
longtime2= System.currentTimeMillis();
while(loop>0) {
String[]trpp=strFlag.split(",");
loop--;
}
System.out.println("Base :"+(System.currentTimeMillis() -time2));
}
結(jié)果為:
flag :2
Base :121592
從結(jié)果上看,這個性能差了可不是一點(diǎn)。
總結(jié),對于一些標(biāo)志位的存儲和判斷來看,要選擇合適的存儲結(jié)構(gòu),非常重要,一方面在存儲上更加節(jié)約時間,另一方面進(jìn)行計(jì)算喝判斷的時候也更加節(jié)約CPU時間,雖然現(xiàn)在計(jì)算機(jī)發(fā)展非常快,CPU和存儲都在飛速的發(fā)展,但是對于計(jì)算機(jī)開發(fā)人員還是多注意這方面的內(nèi)容,節(jié)約資源。往往最后的程序緩慢就是這些微不足道的小問題形成的。
本文檔為原創(chuàng),轉(zhuǎn)載請注明出處。