ByteArrayの分割

パラメータ付きコマンドを、コマンドとパラメータに分割したい。
byte[]のまま処理するか、ReadOnlySpanとして処理するかで、まあ、ReadOnlySpanの方が速いのだろうど、きちんとベンチマークを取ってみた。

public class BenchTarget
{
    public static byte[] SampleBytes = Encoding.UTF8.GetBytes("Command Parameter");

    [Benchmark]
    public int ByteArraySplitBench()
    {
        int sum = 0;

        for(int i = 0;i<100;i++)
        {
            (var left, var right) = ByteArraySplit(SampleBytes);
            sum += left.Length + right.Length;
        }

        return sum;
    }

    public static (byte[] left, byte[] right) ByteArraySplit(byte[] source)
    {
        byte[] left;
        byte[] right;
        for (int i = 0; i < source.Length; i++)
        {
            if (source[i] == (byte)' ')
            {
                left = new byte[i];
                source.AsSpan(0, i).CopyTo(left.AsSpan());
                right = new byte[source.Length - i - 1];
                source.AsSpan(i + 1).CopyTo(right.AsSpan());

                return (left, right);
            }
        }
        left = source;
        right = Array.Empty<byte>();
        return (left, right);
    }

    [Benchmark]
    public int ReadOnlySpanSplitBench()
    {
        int sum = 0;

        for (int i = 0; i < 100; i++)
        {
            ReadOnlySpanSplit(SampleBytes, out var left, out var right);
            sum += left.Length + right.Length;
        }

        return sum;
    }

    public static void ReadOnlySpanSplit(ReadOnlySpan<byte> source, out ReadOnlySpan<byte> left, out ReadOnlySpan<byte> right)
    {
        for (int i = 0; i < source.Length; i++)
        {
            if (source[i] == (byte)' ')
            {
                left = source[0..i];
                right = source[(i + 1)..];
                return;
            }
        }
        left = source;
        right = ReadOnlySpan<byte>.Empty;
    }

}

結果

|                 Method |       Mean |    Error |   StdDev |
|----------------------- |-----------:|---------:|---------:|
|    ByteArraySplitBench | 1,721.1 ns | 33.61 ns | 33.01 ns |
| ReadOnlySpanSplitBench |   590.9 ns |  3.22 ns |  2.51 ns |

ReadOnlySpanだと、使い方に制限が付く場合もあるが、やはりbyte[]のnewが起こらないため、かなり速くなる。

投稿日:
カテゴリー: C#

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です