4

Somewhere I read (rephrased):

If we compare a UTF-8 encoded file VS a UTF-16 encoded file, At some times, the UTF-8 file may give a 50% to 100% larger file size

Am I right to say that the article is wrong because at all times, text encoded in UTF-8 will never give us more than a +50% file size of the same text encoded in UTF-16?

4

4 回答 4

26

答案是在 UTF-8 中,ASCII 只有 1 个字节,但一般来说,包括英语在内的大多数西方语言在这里和那里都使用一些需要 2 个字节的字符,因此实际百分比会有所不同。当以 UTF-8 编码时,希腊语和西里尔语语言都要求其脚本中每个字符至少 2 个字节。

常见的东方语言要求其字符在 UTF-8 中为 3 个字节,但在 UTF-16 中为 2 个字节。但是请注意,“不常见”的东方字符在 UTF-8 和 UTF-16 中都需要 4 个字节。

3 确实只比 2 大 50%。但这仅适用于单个代码点。它不适用于整个文件。

实际百分比无法精确说明,因为您不知道代码的平衡点是在 1 字节还是 2 字节 UTF-8 范围内,还是在 4 字节 UTF-8 范围内。如果亚洲文本中有空格,那么这只是 UTF-8 的字节,但它是 UTF-16 的昂贵的 2 个字节。

这些事情确实有所不同。您只能在精确文本上获得精确数字,而不是在一般文本上。亚洲文本中的代码点占用 UTF-8 的 1、2、3 或 4 个字节,而在 UTF-16 中,它们每个需要 2 或 4 个字节。

案例分析

比较东京上各种语言的维基百科页面,看看我的意思。即使在东方语言中,仍然有大量的 ASCII 代码。仅此一项就使您的数字波动。考虑:

Paras Lines Words Graphs Chars  UTF16 UTF8   8:16 16:8  Language

 519  1525  6300  43120 43147  86296 44023   51% 196%  English
 343   728  1202   8623  8650  17302  9173   53% 189%  Welsh
 541  1722  9013  57377 57404 114810 59345   52% 193%  Spanish
 529  1712  9690  63871 63898 127798 67016   52% 191%  French
 321   837  2442  18999 19026  38054 21148   56% 180%  Hungarian

 202   464   976   7140  7167  14336 11848   83% 121%  Greek
 348   937  2938  21439 21467  42936 36585   85% 117%  Russian

 355   788   613   6439  6466  12934 13754  106%  94%  Chinese, simplified
 209   419   243   2163  2190   4382  3331   76% 132%  Chinese, traditional
 461  1127  1030  25341 25368  50738 65636  129%  77%  Japanese
 410   925  2955  13942 13969  27940 29561  106%  95%  Korean

其中每一个都是保存为文本 而不是HTML 的东京维基百科页面。所有文本都在 NFC 中,而不是在 NFD 中。每一列的含义如下:

  1. Paras 是空白行分隔的文本跨度的数量。
  2. Lines 是换行符分隔的文本跨度的数量。
  3. Words 是空格分隔的文本跨度的数量。
  4. Graphs 是 Unicode 扩展字素簇的数量,有时也称为字形。这些是用户可见的字符。
  5. Chars 是 Unicode 代码点的数量。这些是或应该是程序员可见的字符。
  6. UTF16 是文件存储为 UTF-16 时占用的字节数。
  7. UTF8 是文件存储为 UTF-8 时占用的字节数。
  8. 8:16 是 UTF-8 大小与 UTF-16 大小的比率,以百分比表示。
  9. 16:8 是 UTF-16 大小与 UTF-8 大小的比率,以百分比表示。
  10. 语言是我们在这里讨论的东京页面的哪个版本。

我将这些语言分为西方拉丁语、西方非拉丁语和东方语。观察:

  1. 使用拉丁文字的西方语言在从 UTF-8 转换为 UTF-16 时受到严重影响,其中英语受到的影响最大,增长了 96%,而匈牙利语的影响最小,增长了 80%。都是巨大的。

  2. 不使用拉丁文字的西方语言仍然受到影响,但只有 15-20%。

  3. 东方语言不会像每个人声称的那样在 UTF-8 中受苦!看哪:

    • 在韩语和(简体)中文中,UTF-8 仅比 UTF-16 大 6%。
    • 在日语中,UTF-8 比 UTF-16 大 29%。
    • UTF-8 中的繁体中文实际上比UTF -16 小!事实上,对于这个样本,使用 UTF-16 比使用 UTF-8 的成本高 32%。如果您查看 Lines 和 Words 列,看起来这可能是由于使用了空白。

我希望这能回答你的问题。与以 UTF-16 编码的相同文本相比,以 UTF-8 编码的东方语言的大小根本不会增加 +50% 到 +100%。只有在获取单个代码点时,您才会看到这样的数字,这是一个完全不合理的指标。

于 2011-07-30T17:02:17.183 回答
10

是的,你是对的。U+0800..U+FFFF 范围内的代码点给出了 +50% 的大小。

                   UTF-8   UTF-16
U+0000..U+007F       1        2
U+0080..U+07FF       2        2
U+0800..U+FFFF       3        2
U+010000..U+10FFFF   4        4
于 2011-08-10T08:47:50.893 回答
2

在 UTF-8 中,从 0 到 127 的每个代码点都存储在一个byte中。只有 128 及以上的代码点使用 2、3 存储,实际上最多 6 个字节。

尽管 UTF-8 字符最多可以使用 4 个字节(理论上可能更多),但它不用于包含“几乎所有现代语言”的基本多语言平面。

基本多语言平面的其余部分需要三个字节(其中包含几乎所有常用字符)。Unicode 的其他平面中的字符需要四个字节,其中包括不太常见的 CJK 字符和各种历史脚本。

所以我猜想 100% 的开销虽然在理论上是可能的,但对于典型的现代语言来说是不可能的。你必须使用 Supplementary Multilingual Plane 中的一些奇特的东西,它使用 UTF-8 中的 4 个字节来实现这一点。

对于 HTML 文档或混合文本,可能不需要切换到 UTF-16 以节省空间:

字符 U+0800 到 U+FFFF 在 UTF-8 中使用三个字节,但在 UTF-16 中仅使用两个字节。因此,如果这些字符的数量多于 ASCII 字符,则(例如)中文、日文或印地文文本在 UTF-8 中可能会占用更多空间。这发生在纯文本中,但很少发生在 HTML 文档中。例如,维基百科上的日文 UTF-8 和印地文 Unicode 文章如果保存为 UTF-16,则比原始 UTF-8 版本占用更多空间。

请参阅Wikipedia 上的 UTF-8 到 UTF-16 比较


Joel Spolsky 写了一篇很棒的关于 Unicode 的文章,我真的可以推荐它:

每个软件开发人员绝对、绝对必须了解 Unicode 和字符集的绝对最低要求(没有借口!)

于 2011-07-30T13:45:48.497 回答
0

如果你有一个字节作为字符并添加第二个字节,我会称之为增加 100%,而不是 50%。我想这就是作者的意思。

如果我将X带有N字节/字符的字符写入文件,我将NX在该文件中有字节。因此,您可以看到将每个字符的字节数增加一倍或三倍将对文件大小产生线性影响。

于 2011-07-30T13:40:48.223 回答