Dive into Ofuton

お布団に飛び込もう

BitConverterでGetBytesするよりポインタ使ったほうがメモリに優しい

ykimisaki.hatenablog.jp

byte[]に何かを変換するとき、BitConverter.GetBytesを使わない方がパフォーマンス出る。

GetBytesの中身を見ると、(当然といえば当然だけど)内部で引数の型の大きさ分だけbyte配列をnewしているため、ポインタを使って適当に用意したバッファを使い回した方がメモリに優しい。

GetBytes - http://referencesource.microsoft.com/#mscorlib/system/bitconverter.cs,9108fa2d0b37805b,references

[System.Security.SecuritySafeCritical]  // auto-generated
public unsafe static byte[] GetBytes(int value)
{
    Contract.Ensures(Contract.Result<byte[]>() != null);
    Contract.Ensures(Contract.Result<byte[]>().Length == 4);

    byte[] bytes = new byte[4];
    fixed(byte* b = bytes)
        *((int*)b) = value;
    return bytes;
}

GetBytesを呼んだ回数だけbyte配列もnewされるため、適当にバッファ用意してそこにbyte[]に変換したものをコピーするとよい。
一番上のリンクだと、byte[1024]のバッファに、int[100]をまとめて突っ込んでいた。要点はこんな感じ。

byte[] buf = byte[4];

unsafe{
    fixed(byte* b = &buf[0]) // bufの先頭アドレスのポインタを作成
        *((int*)b) = value;// ポインタに値を入れる(bufに入る)
}

追記

UnityのmonoとBitConverterが微妙にコードが違ったのでこっち(mono/BitConverter.cs at Mono2.12.x-Unity4.x · Unity-Technologies/mono · GitHub)見たほうがいいかも