私が正しく理解していれば、UTF-32は宇宙のすべてのキャラクターを処理できます。代理ペアを使用することで、UTF-16も可能です。では、UTF-16の代わりにUTF-32を使用する正当な理由はありますか?
7 に答える
UTF-32 では、Unicode 文字は常に 4 バイトで表されるため、UTF-16 では文字がさまざまなバイト数で表されるため、解析コードは UTF-16 文字列よりも簡単に記述できます。欠点としては、UTF-32 チャタクターは常に4 バイトを必要とし、主に英語の文字を扱う場合は無駄になる可能性があります。そのため、UTF-16 を使用するか UTF-32 を使用するかは、要件に応じた設計上の選択です。
サロゲートペアを処理することはほとんどの場合「特殊なケース」を処理するため、UTF-16ではなくUTF-32を処理することを好む人がいるかもしれません。これらの特殊なケースを処理する必要があるということは、処理するためにバグが忍び寄る可能性がある領域があることを意味します。それらを誤って処理します(または、それらに対処することをまったく忘れる可能性が高くなります)。
UTF-32のメモリ使用量の増加が問題にならない場合は、複雑さを軽減することで、UTF-32を選択するのに十分な利点になる可能性があります。
The Unicode Consortium からの優れたドキュメントもあります。
Copyright © 1991–2009 Unicode, Inc. Unicode 標準、バージョン 5.2
表面的には、UTF-32 は固定幅のエンコーディング形式であるため、内部処理コードの Unicode エンコーディング形式の明らかな選択のように見えます。これは、C および C++ に準拠してバインドできます
wchar_t
。つまり、そのようなプログラミング言語は、組み込みのサポートと、プログラマーが利用できる既製の文字列 API を提供する可能性があります。ただし、UTF-16 には多くの相殺する利点があり、実装者は代わりにそれを内部処理コードとして選択する可能性があります。3 つのエンコーディング形式はすべて、文字ごとに最大で 4 バイト (または 32 ビット) のデータを必要としますが、実際には、実際のデータセットのほとんどすべての場合で UTF-32 は、UTF-16 が必要とするストレージの 2 倍を占有します。したがって、一般的な戦略は、内部文字列ストレージに UTF-16 または UTF-8 を使用させ、個々の文字を操作するときは UTF-32 を使用させることです。UTF-32 対 UTF-16。平均して、すべての UTF-16 データの 99% 以上が単一のコード単位を使用して表現されています。これには、テキストに対する特殊な操作でソフトウェアが処理する必要がある一般的な文字のほぼすべてが含まれます (たとえば、書式制御文字)。結果として、ほとんどのテキスト スキャン操作では、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 コード ポイントは、「文字」に対するユーザーの期待と必ずしも一致しません。たとえば、次のものは単一のコード ポイントでは表されません。韓国語の結合ジャモシーケンス。またはデバナーガリー接続詞「ksha」。一部の Unicode テキスト処理では、このような文字列をテキスト要素として認識して処理する必要があるため、UTF-32 の固定幅エンコーディング形式の利点は、テキスト要素の処理に本質的に可変幅の性質があるため、多少相殺されます。Unicode Technical Standard #18、「Unicode 正規表現」を参照してください。一般的に実装されているプロセスが、「文字」のアイデンティティに対するユーザーの期待のために本質的に可変幅のテキスト要素を処理する例については、「Unicode 正規表現」を参照してください。UTF-8。UTF-8 は、使用されるバイト数に関してかなりコンパクトです。UTF-8 の 3 バイト コード単位シーケンスを必要とする漢字やハングル音節を使用する、中国語、日本語、韓国語などの東アジアの実装に使用する場合、実際にはサイズがかなり不利になるだけです。また、UTF-8 は、処理の点で、他のエンコーディング形式よりも大幅に効率が低くなります。バイナリソート。UTF-8 文字列のバイナリ ソートは、Unicode コード ポイントのバイナリ ソートと同じ順序になります。これは明らかに、UTF-32 文字列のバイナリ ソートと同じ順序です。
一般的な構造
BMP 文字 (U+0000..U+FFFF の範囲) のみを扱う場合、3 つのエンコーディング形式はすべて、バイナリ文字列の比較または文字列の並べ替えに対して同じ結果をもたらします。ただし、補助文字 (U+10000..U+10FFFF の範囲) を扱う場合、UTF-16 バイナリ順は Unicode コード ポイント順と一致しません。これは、たとえば、UTF-16 システムと UTF-8 または UTF-32 システムの間など、バイナリソートリストと相互運用しようとすると複雑になる可能性があります。ただし、バイナリ順序を使用するのではなく、特定の言語またはロケールの規則に従って並べ替えられたデータの場合、データはエンコード形式に関係なく同じ順序になります。
UTF-8 は、任意の Unicode 文字を表すこともできます!
テキストの大部分が英語の場合、utf-8 を使用すると多くのスペースを節約できますが、一部の文字は 1 バイト以上を占めるため、文字のインデックス作成は O(1) ではありません。
スペースが速度ほど重要でない場合は、索引付けが O(1) であるため、utf-32 の方が適切です。
英語以外のテキストの場合、UTF-16 は utf-8 よりも優れている可能性があります。これは、utf-8 では一部の文字が 3 バイトを占める状況があるためです。utf16 では 2 バイトしか使用しません。
短い答え:いいえ。
より長い答え: はい、メモを取得しなかった他のものとの互換性のためです。
皮肉ではない答え: スペースの使用よりもインデックス作成の速度を気にする場合、または何らかの中間形式として、またはキャッシュの問題よりもアライメントの問題が重要なマシンで、または...
一般に、基礎となるプラットフォームの文字列データ型/エンコーディングを使用するだけです。これは、多くの場合 (Windows、Java、Cocoa...) UTF-16 であり、UTF-8 または UTF-32 の場合もあります。これは主に歴史的な理由によるものです。3 つの Unicode エンコーディングにはほとんど違いがありません。3 つすべてが明確に定義され、高速で堅牢であり、すべての Unicode コード ポイント シーケンスをエンコードできます。固定幅エンコーディングであるという UTF-32 のユニークな機能 (各コード ポイントが正確に 1 つのコード単位で表されることを意味します) は、実際にはほとんど役に立ちません。メモリ管理レイヤーは、コードの数と幅について知る必要があります。ユーザーは抽象的な文字や書記素に興味を持っています。Unicode 標準で言及されているように、Unicode アプリケーションは、結合された文字、合字などをとにかく処理し、サロゲート ペアを処理する必要があります。
もし私が世界を再発明するとしたら、おそらく UTF-32 を選ぶでしょう。なぜなら、それは単に最も複雑でないエンコーディングだからです。