天天看點

如何選擇使用字元串還是數字呢?

在我多年的開發經驗中,經常發現的一個情況就是,很多項目的對象字段或者是資料庫字段本來是數字類型的,卻被定義成字元串類型,這無關痛癢嗎?

對于小項目來說,可能沒什麼影響,反正隻要業務邏輯正确即可,性能沒什麼問題,因為資料也不多,使用者也不多。

然而,對于大資料處理來說,這個可不是小事,從字元串替換為數字類型,可以極大地節省記憶體、磁盤存儲以及網絡帶寬,減少io的代價,而且很多資料結構和算法使用數字類型比字元串要更快。

我們來看一個例子,假設你有很多的日志需要處理,而每條日志都有一個唯一的辨別,辨別類似這樣的格式:

看到這些辨別,你怎麼想?我的第一反應應該是數字,可是怎麼有個f呢?我想可以把它當做16進制。後來發現可以把f當做負号,這就是一個64位的長整型。

那麼如果你把這些辨別當成字元串,會有什麼不同呢?

當然有,如果你每秒要處理這樣的日志百萬或者千萬條,每條處理結果可能會包含百萬或者千萬個這樣的辨別元素構成的集合,這個不同就會展現的非常明顯。

下面,我們來分析一下辨別3832154813577306424的存儲占用情況:

1、記憶體占用

當做字元串:我們知道,java中字元串是由字元構成的,一個字元是由2個位元組構成的(這是java的悲劇了),上述辨別有19個字元,是以,占用的記憶體大小為:19*2+4=42(位元組),+4是因為字元串使用一個整型儲存字元串的哈希值。

當做數字:如當做長整型,則占用的記憶體大小為8位元組。

這裡有5倍以上的差距了吧。

2、序列化位元組大小

當我們需要通過網絡傳輸這些辨別或者需要把這些辨別存儲到磁盤中的時候,我們就需要把這些辨別轉換為位元組數組,如何轉換為位元組數組呢?我們可以使用多種編碼方式。

當做字元串:我們知道,java中字元串轉換為位元組數組可以使用多種編碼方式,我們看看常見的編碼方式對如上字元串編碼之後的位元組數:

輸出如下:

這裡有2倍以上的差距了吧。

那麼我們如何在長整型和位元組數組之間轉換呢?