优势
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 编码应用更普遍? 参与回答: 林建入- 回答编辑器