優勢
UTF-8
- 兼容 ASCII
- 能適應許多 C 庫中的 \0 結尾慣例
- 沒有字節序問題
- 良好的多語種支持(相對 GBK 等跟語種綁定的編碼方式)
- 以英文和西文符號比較多的場景下(例如 HTML/XML),編碼較短
- 因爲是變長,字符空間足夠大,將來 Unicode 新標準收錄更多字符,UTF-8 也能妥妥的兼容,所以不會再出現 UTF-16 那樣的尷尬
- 不存在大小端字節序問題,信息交換時很是便捷
- 容錯性高,局部的字節錯誤(丟失、增長、改變)不會致使連鎖性的錯誤,由於 UTF-8 的字符邊界很容易檢測出來,這是一個巨大的優勢(正是爲了實現這一點,我們中日韓人民不得不忍受 3 字節 1 個字符的苦日子)
UTF-16(應該不算優勢)
- 最流行的操做系統和 UI framework 的內部字符串表達都是 UTF-16
- Windows API 的 Wide Char 表達是 UTF-16: Unicode (Windows), L"" 表示是轉換爲 wide char。
- Cocoa 的 NSString 和 Core Foundation 的 CFString 內部表達都是 UTF-16,因此其實 OS X 和 iOS 內部處理都用的是 UTF-16。
- Java String 的內部表達是 UTF-16,因此大量跨平臺程序和 Android 程序其實內部也在用 UTF-16。
- 在計算字符串長度、執行索引操做時速度很快。
注:可是UTF-16也是變長的,Unicode擴展到9萬多之後,也要經過變長來支持了。 具體緣由參照知乎回答: 編程語言的字符編碼選擇UTF-8和UTF-16的優缺點?前端
UTF-32
- 定長編碼,utf32 表示任何字符都用 4 字節,讀到內存中是個均勻的整形數組,因而咱們能夠很方便地隨機訪問任何一個字符
- 因爲是定長,索引比變長的要快,你想訪問一個字符串中的第 n 個字符,utf32 直接偏移 n 個整形距離便可,utf8 得從第一個字節一個字一個字地日後蹦,很是蛋疼。
補充: UTF 32 也不想理想中那麼方便索引,主要是 emoji 的鍋,舉兩個例子:1、Emoji 裏面的國旗其實由兩個字符組成,稱爲 region indicator,每一個字符是一個 region indicator symbol letter,從 A 到 Z,U+1F1E6 到 U+1F1FF。好比說法國國旗就是用 FR 的對應 region indicator symbol letter 來表示的。Swift 的 String 自稱有較好的 Unicode 支持,但對這樣的字符的長度目前給的仍是 2(Unicode 8.0 標準),而實際上 Unicode 9.0 已經要求把它們看做一個字符了。2、爲了政治正確,人們引入了帶膚色的 emoji 表情,它們是由普通表情和一個表明顏色的 emoji 字符組成。因而乎,若是寫編輯器的話,無論怎麼樣都要 O(n) 來計算可見字符的長度的(這尚未考慮韓語那種三個字符疊成一個字符的狀況),因此前端們很可憐的。 參見 劉閩晟 回答,連接編程
缺點
UTF-8
- 文化上的不平衡——對於歐美地區一些以英語爲母語的國家 UTF-8 簡直是太棒了,由於它和 ASCII 同樣,一個字符只佔一個字節,沒有任何額外的存儲負擔;可是對於中日韓等國家來講,UTF-8 實在是太冗餘,一個字符居然要佔用 3 個字節,存儲和傳輸的效率不但沒有提高,反而降低了。因此歐美人民經常堅決果斷的採用 UTF-8,而咱們卻總是要猶豫一下子。
- 變長字節表示帶來的效率問題——你們對 UTF-8 疑慮重重的一個問題就是在於其由於是變長字節表示,所以不管是計算字符數,仍是執行索引操做效率都不高。爲了解決這個問題,經常會考慮把 UTF-8 先轉換爲 UTF-16 或者 UTF-32 後再操做,操做完畢後再轉換回去。而這顯然是一種性能負擔。
UTF-16
- UTF-16 能表示的字符數有 6 萬多,看起來不少,可是實際上目前 Unicode 5.0 收錄的字符已經達到 99024 個字符,早已超過 UTF-16 的存儲範圍;這直接致使 UTF-16 地位頗爲尷尬——若是誰還在想着只要使用 UTF-16 就能夠高枕無憂的話,恐怕要失望了。
- UTF-16 存在大小端字節序問題,這個問題在進行信息交換時特別突出——若是字節序未協商好,將致使亂碼;若是協商好,可是雙方一個採用大端一個採用小端,則必然有一方要進行大小端轉換,性能損失不可避免(大小端問題其實不像看起來那麼簡單,有時會涉及硬件、操做系統、上層軟件多個層次,可能會進行屢次轉換)。
- 另外,容錯性低有時候也是一大問題——局部的字節錯誤,特別是丟失或增長可能致使全部後續字符所有錯亂,錯亂後要想恢復,可能很簡單,也可能會很是困難。(這一點在平常生活裏你們感受彷佛可有可無,可是在不少特殊環境下倒是巨大的缺陷)。
該如何選擇
簡要回答: UTF-8,用於存儲及傳輸 UTF-32,用於程序內存中數組
緣由:網絡
- UTF-8靈活,在互聯網通訊中被編碼影響小,兼容性強。
- UTF-32定長,在內存中程序處理優秀,查詢快。
由於不管是 UTF-8 和 UTF-16/32 都各有優缺點,所以選擇的時候應當立足於實際的應用場景。例如在個人習慣中,存儲在磁盤上或進行網絡交換時都會採用 UTF-8,而在程序內部進行處理時則轉換爲 UTF-16/32。對於大多數簡單的程序來講,這樣作既能夠保證信息交換時容易實現相互兼容,同時在內部處理時會比較簡單,性能也還算不錯。(基本上只要你的程序不是 I/O 密集型的均可以這麼幹,固然這只是我粗淺的認識範圍內的經驗,極可能會被無情的反駁)。編程語言
整理自: 知乎 - 爲何 UTF-8 編碼比 UTF-16 編碼應用更普遍? 參與回答: 林建入- 回答編輯器