てくメモ

trivial な notes

【C#】Span<byte>.SequenceEqual に代えて数値型で == する方法の確認

下記スライドを学習した際、記事名の内容の効用が気になったので、マイクロベンチマークする。


byte列の照合を取る際は通常、SequenceEqualメソッドを用いる。比較するReadOnlySpan<byte>が静的に定まればアロケーションもない。

代えて、サイズが適するなら Span を数値型として読むことで単に==でき、それが最速というのがスライドの内容。

文字列、Span<byte>.SequenceEqualintで BenchmarkDotNet。

private static ReadOnlySpan<byte> Target => "%PDF-1.5"u8;

private static bool AsString(ReadOnlySpan<byte> span) => Encoding.ASCII.GetString(span[..4]) == "%PDF";
private static bool AsReadOnlySpan(ReadOnlySpan<byte> span) => span[..4].SequenceEqual("%PDF"u8);
private static bool AsNumber(ReadOnlySpan<byte> span) => Unsafe.ReadUnaligned<int>(ref MemoryMarshal.GetReference(span)) == 1178882085;

[Benchmark]
public bool String() => AsString(Target);
[Benchmark(Baseline = true)]
public bool Span() => AsReadOnlySpan(Target);
[Benchmark]
public bool Int() => AsNumber(Target);
 Method | Mean       | Error     | StdDev    | Ratio | RatioSD | Gen0   | Allocated | Alloc Ratio |
------- |-----------:|----------:|----------:|------:|--------:|-------:|----------:|------------:|
 String | 16.3037 ns | 3.7117 ns | 0.2034 ns | 8.317 |    0.07 | 0.0102 |      32 B |          NA |
 Span   |  1.9603 ns | 0.2682 ns | 0.0147 ns | 1.000 |    0.00 |      - |         - |          NA |
 Int    |  0.0190 ns | 0.0549 ns | 0.0030 ns | 0.010 |    0.00 |      - |         - |          NA |

ナノ秒とはいえ、ふた桁速くて笑った。

引き出しには入れておきたい。