下記スライドを学習した際、記事名の内容の効用が気になったので、マイクロベンチマークする。
byte
列の照合を取る際は通常、SequenceEqual
メソッドを用いる。比較するReadOnlySpan<byte>
が静的に定まればアロケーションもない。
代えて、サイズが適するなら Span を数値型として読むことで単に==
でき、それが最速というのがスライドの内容。
文字列、Span<byte>.SequenceEqual
、int
で 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 |
ナノ秒とはいえ、ふた桁速くて笑った。
引き出しには入れておきたい。