有没有理由比UTF-8更喜欢UTF-16?

时间:2010-05-29 11:27:33

标签: c# java unicode utf-8 utf-16

检查UTF-16和UTF-8的属性,我找不到任何理由更喜欢UTF-16。

然而,检查Java和C#,它看起来像字符串和字符默认为UTF-16。我认为这可能是出于历史原因,或者出于性能原因,但找不到任何信息。

有谁知道为什么这些语言选择了UTF-16?我也有正当理由这样做吗?

编辑:与此同时,我还发现了this answer,这似乎很相关并且有一些有趣的链接。

7 个答案:

答案 0 :(得分:32)

与UTF-8(通常需要3个字节)相比,东亚语言通常需要更少的UTF-16存储空间(2个字节足以满足99%的东亚语言字符)。

当然,对于西方联盟,UTF-8通常较小(1字节而不是2字节)。对于像HTML这样的混合文件(其中有很多标记),这非常多。

处理用户模式应用程序的UTF-16比处理UTF-8更容易,因为代理对的行为几乎与组合字符的行为相同。因此,UTF-16通常可以作为固定大小的编码进行处理。

答案 1 :(得分:10)

@Oak:这个评论太长了......

我不知道C#(并且会非常惊讶:这意味着他们只是复制了Java 太多)但是对于Java来说它很简单:Java是在Unicode 3.1出现之前构思的。 / p>

因此,代码点少于65537,因此每个Unicode代码点仍适用于16位,因此Java char 就诞生了。

当然这导致了疯狂的问题,这些问题仍然影响着今天的Java程序员(比如我),你有一个方法 charAt ,在某些情况下它既没有返回Unicode字符也没有返回Unicode代码点,一个方法(在Java 5中添加) codePointAt ,它接受的参数不是您想要跳过的代码点数量! (您必须向 codePointAt 提供要跳过的Java char 的数量,这使它成为String类中最不易理解的方法之一。)

所以,是的,这绝对是大多数Java程序员的狂热和混乱(大多数人甚至都不知道这些问题),是的,这是出于历史原因。至少,这是人们在这个问题之后生气的原因:但是因为Unicode 3.1还没有出现

:)

答案 2 :(得分:7)

我认为使用UTF-16的C#派生自内部使用UTF-16的Windows NT系列操作系统。

我认为Windows NT在内部使用UTF-16有两个主要原因:

  • 对于内存使用:UTF-32浪费了一个 要编码的空间很多
  • 表现:UTF-8要难得多 解码比UTF-16。在UTF-16中,字符也是 基本多语言平面字符(2个字节)或代理项 配对(4个字节)。 UTF-8字符 可以是1到4之间的任何地方 字节。

与其他人的回答相反 - 您不能将UTF-16视为UCS-2。如果要正确迭代字符串中的实际字符,则必须使用对unicode友好的迭代函数。例如,在C#中,您需要使用StringInfo.GetTextElementEnumerator()

有关详细信息,请参阅维基上的此页面:http://en.wikipedia.org/wiki/Comparison_of_Unicode_encodings

答案 3 :(得分:3)

这取决于预期的字符集。如果您期望在7位ASCII范围之外大量使用Unicode代码点,那么您可能会发现UTF-16将比UTF-8更紧凑,因为一些UTF-8序列的长度超过两个字节。

此外,出于效率原因,Java和C#在索引字符串时不考虑代理对。当使用以UTF-8序列表示占用奇数个字节的代码点时,这会完全崩溃。

答案 4 :(得分:3)

UTF-16可以更有效地表示某些语言中的字符,例如中文,日文和韩文,其中大多数字符可以用一个16位字表示。一些很少使用的字符可能需要两个16位字。 UTF-8通常更有效地表示来自西欧字符集的字符 - UTF-8和ASCII在ASCII范围(0-127)上是等效的 - 但对亚洲语言效率较低,需要三或四个字节来表示字符可以用UTF-16中的两个字节表示。

UTF-16作为Java / C#的内存格式具有优势,因为基本多语言平面中的每个字符都可以用16位表示(参见Joe的答案)和UTF-16的一些缺点(例如令人困惑的代码依赖于\ 0终结符)不太相关。

答案 5 :(得分:2)

对于许多(大多数?)应用程序,您将只处理Basic Multilingual Plane中的字符,因此可以将UTF-16视为固定长度编码。

因此,您可以避免使用UTF-8等可变长度编码的所有复杂性。

答案 6 :(得分:2)

如果我们仅在谈论纯文本,那么UTF-16在某些语言中可能会更紧凑,其中日语(约20%)和中文(约40%)是最好的例子。当您比较HTML文档时,优点就完全相反了,因为UTF-16将为每个ASCII字符浪费一个字节。

为简单起见或提高效率:如果在编辑器应用程序中正确实现Unicode,复杂性将相似,因为UTF-16始终不会始终将代码点编码为单个数字,并且单个代码点通常不是分割文本的正确方法

鉴于在最常见的应用程序中,UTF-16的紧凑性较小,并且实现起来同样复杂,因此,如果您有一个完全封闭的生态系统来定期存储或存储UTF-16,那么之所以选择UTF-16而不是UTF-8是唯一的原因。完全在复杂的书写系统中传输纯文本,而无需压缩。

使用zstd或LZMA2压缩后,即使对于100%的中文纯文本,其优势也被完全消除;使用gzip时,带有大约3000个唯一字素的中文文本的UTF-16优势约为4%。