2020年09月16日
川俣晶の縁側ソフトウェアC# コーディング How To total 603 count

【入門級】byte?とshortはどちらがメモリ効率が良いか?

Written By: 川俣 晶連絡先

0~255と無効値を保存したい §

 0~255と無効値、つまり257種類の値を保存するにはどうすれば良いでしょうか。

 第1のアイデアはbyte?の利用です。この型なら0~255とnull値を表現できます。無駄がありません。

 第2のアイデアは、byte型は256種類の値しか識別できない以上、もっと幅の大きいshort型の利用です。-1が無効値と決めておけば問題ありませんが、65536種類の値を識別できて無駄が大きいと言えます。

 さて、どちらのメモリ効率が良いでしょう?

実はshortが勝つ §

 以下のサンプルソースは1000000個の配列を作って、その前後のメモリ使用量の大きさを比較しています。

 実行結果を見ると分かる通り、byte?とshortの使用量は同じです。

なぜ無駄がないように見えたbyte?は勝てないのか? §

 byte型は8bitです。byte?型はそれに加えて値を持っているかどうかを示すbool値を持ちます。bool値は8bitのメモリを占有します。合計16bitです。

 一方でshort型は16bitです。

 どちらも16bitなので必要メモリ量は同じです。

罠の数々 §

  • shortをbyte?に書き換えてもメモリの節約にはならない
  • short?はshort 16bit+bool 8bitで24bitで済むように思えるが実際は32bitのintと消費量は同じである。アドレスを整列するためにパディングのバイトが挿入されるからだ。ビギナーは整列の意味を理解しなくても良いが、消費量が狂うことがあることは知っておくと良い
  • 同様にint?はint 32bit+bool 8bitで40bitで済むように思えるが実際は64bitのlongと消費量は同じである。

参考リンク §

整数数値型 (C# リファレンス)

null 許容値型 (C# リファレンス)

 個々の型は何bitか。それをnull許容型にすると何bit増えるかを確認しておこう。これを知っておくとメモリ効率の高いプログラムを書けるようになり、メモリ効率が良いと実行速度も速くなる可能性がある。(メモリ効率が良いとCPUのキャッシュに入りやすくなるので)

リポジトリ §

https://github.com/autumn009/cshowto

NullableByteVSShort §

using System;

class Program

{

    private static T[] sub<T>(string label)

    {

        long start = GC.GetTotalMemory(true);

        T[] array = new T[1000000];

        Console.WriteLine($"{label} {GC.GetTotalMemory(true) - start}");

        return array;

    }

    static void Main()

    {

        sub<byte?>("byte?");

        sub<short>("short");

        sub<short?>("short?");

        sub<int>("int");

        sub<int?>("int?");

        sub<long>("long");

    }

}

実行結果

byte? 2000024

short 2000024

short? 4000024

int 4000024

int? 8000024

long 8000024

COOL C# CREW

C#ハウツー連載の解説増量、カラーのソース、新規書き下ろし追加の読みやすい単行本はこちら。

C#ハウツー: 逆引き入門・こんな機能はどう書くの?