Unicode 如果我们有代理项对,为什么要使用UTF-32而不是UTF-16?

Unicode 如果我们有代理项对,为什么要使用UTF-32而不是UTF-16?,unicode,surrogate-pairs,Unicode,Surrogate Pairs,如果我理解正确,UTF-32可以处理宇宙中的每个角色。UTF-16也可以,通过使用代理项对。那么,使用UTF-32而不是UTF-16有什么好的理由吗?简短回答:没有 更长的回答:是的,为了与备忘录中没有提到的其他东西兼容 不那么讽刺的回答:如果您更关心索引的速度而不是空间使用,或者作为某种中间格式,或者在对齐问题比缓存问题更重要的机器上,或者……在UTF-32中,unicode字符始终由4个字节表示,因此解析代码比UTF-16字符串更容易编写,因为在UTF-16中,字符由不同数量的字节表示。另一

如果我理解正确,UTF-32可以处理宇宙中的每个角色。UTF-16也可以,通过使用代理项对。那么,使用UTF-32而不是UTF-16有什么好的理由吗?

简短回答:没有

更长的回答:是的,为了与备忘录中没有提到的其他东西兼容


不那么讽刺的回答:如果您更关心索引的速度而不是空间使用,或者作为某种中间格式,或者在对齐问题比缓存问题更重要的机器上,或者……

在UTF-32中,unicode字符始终由4个字节表示,因此解析代码比UTF-16字符串更容易编写,因为在UTF-16中,字符由不同数量的字节表示。另一方面,UTF-32聊天工具通常需要4个字节,如果您主要使用的是英语字符,这可能会造成浪费。因此,它是一种设计选择,取决于您的需求,是使用UTF-16还是UTF-32。

UTF-8也可以表示任何unicode字符

如果您的文本大部分为英文,那么使用utf-8可以节省大量空间,但索引字符不是O(1),因为有些字符占用的空间超过一个字节

如果空间对您的情况不如速度重要,那么utf-32更适合您,因为索引是O(1)


对于非英语文本,UTF-16可能比UTF-8更好,因为在UTF-8中,有些字符占用3个字节,而在utf16中,它们只占用两个字节。

有人可能更喜欢使用UTF-32而不是UTF-16,因为处理代理项对几乎总是处理“特殊情况”,而必须处理这些特殊情况意味着你有可能因为错误地处理它们(或者更可能的是忘记处理它们)而让bug潜入其中


如果增加UTF-32的内存使用不是问题,那么降低的复杂性可能足以成为选择它的优势。

可能有一些很好的理由,但其中之一是加快索引/搜索,即在数据库等中

使用UTF-32,您知道每个字符有4个字节。使用UTF-16,您不知道任何特定字符的长度

例如,有一个函数返回字符串的第n个字符:

char getChar(int index, String s );
如果您使用具有直接内存访问的语言(例如C)进行编码,那么在UTF-32中,此函数可能与一些指针算术(
s+(4*index)
)一样简单,这将是一些O(1)量


但是,如果您使用的是UTF-16,则必须遍历字符串,边走边解码,这将是O(n)。

这也是Unicode联盟提供的一个很好的文档

版权所有©1991–2009 Unicode,Inc.Unicode标准,版本5.2

从表面上看,UTF-32似乎是内部处理代码的Unicode编码形式的明显选择,因为它是一种固定宽度的编码形式。它可以与C和C++ ++代码> WCARYTT < /COD>绑定,这意味着这样的编程语言可以提供程序员可以接受的内置支持和现成的字符串API。然而,UTF-16具有许多抵消优势,这可能导致实现者选择它作为内部处理代码。 虽然所有三种编码形式的每个字符最多需要4个字节(或32位)的数据,但实际上,在几乎所有情况下,UTF-32对真实数据集的占用都是UTF-16所需存储空间的两倍。因此,一种常见的策略是让内部字符串存储使用UTF-16或UTF-8,但在处理单个字符时使用UTF-32

UTF-32与UTF-16。平均而言,超过99%的所有UTF-16数据使用单代码单元表示。这包括软件需要处理的几乎所有文本特殊操作的典型字符,例如格式控制字符。因此,大多数文本扫描操作根本不需要解压缩UTF-16代理项对,而是可以安全地将它们视为字符串的不透明部分。 对于许多操作,UTF-16与UTF-32一样易于处理,而且UTF-16作为处理代码的性能往往相当好。UTF-16是大多数支持Unicode的实现所选择的内部处理代码。除了Unix平台,UTF-16提供了紧凑大小的正确组合,并能够处理BMP之外的偶然字符。 UTF-32在简化软件编码设计和维护方面有一定的优势。由于字符处理是固定宽度的,UTF-32处理不需要在软件中维护分支来测试和处理UTF-16补充字符所需的双代码单元元素。相反,大表中的32位索引并不是特别高效的内存。为了避免此类索引带来的大量内存损失,Unicode表通常被作为多级表处理(请参阅第5.1节“转换到其他标准的代码”中的“多级表”)。在这种情况下,32位代码点值被分割成更小的范围,以允许分段访问表。即使在典型的UTF-32实现中也是如此。 对于相同的数据,UTF-32作为处理代码的性能实际上可能比UTF-16的性能差,因为额外的内存开销意味着缓存限制将被更频繁地超过,内存分页将更频繁地发生。对于处理器设计对16位对齐访问施加惩罚但内存非常大的系统,这种影响可能不太明显。 在任何情况下,Unicode代码点都不一定符合用户对“字符”的期望。例如,以下代码点不由单个代码点表示:组合字符序列,如;骗局