C#:何がより多くのメモリを消費しますか?文字列またはバイト?
「MyText」という行があるとしましょう。その行は、バイトまたは文字列として、より多くのメモリを消費しますか?
これは、バイト配列の文字エンコードによって異なります。任意の文字列をバイトの配列に変換できますが、エンコーディングを選択する必要があります。単一の標準または正しいエンコーディングはありません。以前ASCIIと呼ばれていたものは、英語圏以外では役に立たない。
ほとんどのエンコーディングでは、「マイテキスト」の長さは7バイトです。ただし、ヨーロッパのアクセント付き文字または日本語の文字をいくつか投入すると、それら(表現できる場合)はそれぞれ1バイトまたは2バイトを超える場合があります。一部のエンコーディングでは、一部のテキスト文字列では、バイト配列表現がで使用される内部Unicode表現よりも大きくなる場合がありますSystem.String
。
Unicodeであるということは、文字列が1文字あたり1バイト以上かかることを意味するのではなく、1文字あたり1バイト以上かかる可能性があることを意味します。
何がより多くのメモリを消費しますか?
したがって、メモリ内表現のサイズについて質問しています。.netは文字列にUTF-16を使用します。これは、この16進ダンプ(UTF-16LE)に見られるように、例が14バイトで表されることを意味します。
4d 00 79 00 20 00 54 00 65 00 78 00 74 00
バイト配列のサイズは、テキストを表すために使用するエンコーディングによって異なります。UTF-16を使用する場合は、次のようになります
Encoding.Unicode.GetBytes(string)
明らかに同じ14バイトを取得します。代わりにUTF-8を使用する場合:
Encoding.UTF8.GetBytes(string)
7バイトの配列を取得します。
4d 79 20 54 65 78 74
この例ではASCII文字セットで使用可能な文字のみを使用しているため、これはASCIIと同じサイズ(および同じ表現)です。これらの文字はすべて、定義によれば、UTF-8でも同じです。
代わりに非ASCII文字、たとえば日本語の「日」を使用する場合、UTF-8エンコーディングには3バイトが必要になります。
e6 97 a5
UTF-16に必要なのは2バイトだけです。
e5 65
日本語の文字をASCIIに変換しようとすると、例外が発生するか、単に「?」を使用します。Encoding
ASCIIはASCII文字以外のものを表すことができないため、構成方法によっては文字。
もう1つのわずかに異なる例、ヨーロッパの文字「ä」。UTF-8で2バイト:
c3 a4
また、UTF-16では2バイト:
e4 00
ASCIIはこの文字を表すことができません。
要約すると、消費されるメモリは、文字列内の実際のデータと、それを表すために使用するエンコーディングによって異なります。
上記のすべては、生データのみのメモリ消費量について説明しています。合計メモリ消費量を計算するには、長さなど、すべての配列と文字列の一部であるメタデータも含める必要があることに注意してください。 .net文字列の場合、ヌルターミネータ(値が「0」の追加の2バイト)。メタデータのバイト数は一定で比較的小さいため、文字列と配列の違いは、非常に小さいテキストが大量にある場合にのみ問題になります。
どちらもかなり近いです。唯一の本当の答え:
フレームワーク/アーキテクチャでプロファイルします。
文字列のコピーが複数ある場合を除いて、バイト配列はより少ないメモリを使用します。その場合、文字列は文字列テーブルのおかげでより少ないメモリを使用します。
しかし、本当の問題は、それは本当に重要なのかということです。文字列をバイトの配列として格納するのではなく、文字列として使用することには多くの利点があります。
あなたの質問は非常に狭かったので、詳細はわかりませんが、私は時期尚早の最適化の匂いがします。
バイト配列。これにより、テキストがASCII(1文字あたり1バイト)文字として格納されますが、.NET文字列はより大きなUnicodeを使用します。ただし、.NET文字列の方がおそらく便利であり、大規模なアプリケーションでは、違いが大きな違いを生むことはないことを覚えておいてください。
(.NET文字列でASCII文字を使用する場合でも、文字はそれぞれ1バイトのみであることに注意してください)
ここには、文字列が占めるスペースの量、およびStringBuilderとインスタンスの割り当てとのさまざまな相互作用の方程式を示す優れたブログ投稿があります。