😃
.NET6でいつの間にかGuidがreadonly structになっていた
パフォーマンス改善のために導入されたreadonly struct
ですが、その改善は長らくGuid
構造体には適用されていませんでした。
UUIDの.NET標準の実装であるGuid
構造体は何かと使う機会も多かったので、この改善がいつになったら適用されるのかな~と首を長くして待っていたのですが、.NET6でreadonly struct
になっていることについ先日気が付きました。
いったいいつの間に…と思いちょっと調べてみたら.NET6からreadonly
になったようです。
2年前の11月にコミットが入っていますね。
ベンチマーク
さてreadonly struct
になったということはin
引数で渡したときのパフォーマンスが改善されることが期待されます。.NET5と.NET6でどれだけ差が出ているのか、早速ベンチを取ってみましょう。
コードは以下のようにしてみました。
できるだけin
引数の差だけ確認したいのと、最適化によるメソッド呼び出し削除を抑制するため、Guid
のメソッドで一番処理が軽そうなToByteArray
を呼び出して戻り値を取得しています。
using System;
using BenchmarkDotNet.Attributes;
namespace GuidBench
{
[MemoryDiagnoser]
public class Benchmarks
{
public static byte[] ToByteArrayNormal(Guid id) => id.ToByteArray();
public static byte[] ToByteArrayIn(in Guid id) => id.ToByteArray();
private readonly Guid _id = Guid.NewGuid();
[Benchmark]
public byte[] ToByteArrayNormal() => ToByteArrayNormal(_id);
[Benchmark]
public byte[] ToByteArrayIn() => ToByteArrayIn(_id);
}
}
ベンチマークの結果
// * Summary *
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.22000
11th Gen Intel Core i5-11400F 2.60GHz, 1 CPU, 12 logical and 6 physical cores
.NET Core SDK=6.0.300
[Host] : .NET Core 5.0.17 (CoreCLR 5.0.1722.21314, CoreFX 5.0.1722.21314), X64 RyuJIT
DefaultJob : .NET Core 5.0.17 (CoreCLR 5.0.1722.21314, CoreFX 5.0.1722.21314), X64 RyuJIT
Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|
ToByteArrayNormal | 3.976 ns | 0.0299 ns | 0.0249 ns | 0.0064 | - | - | 40 B |
ToByteArrayIn | 3.960 ns | 0.0272 ns | 0.0255 ns | 0.0064 | - | - | 40 B |
// * Summary *
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.22000
11th Gen Intel Core i5-11400F 2.60GHz, 1 CPU, 12 logical and 6 physical cores
.NET Core SDK=6.0.300
[Host] : .NET Core 6.0.5 (CoreCLR 6.0.522.21309, CoreFX 6.0.522.21309), X64 RyuJIT
DefaultJob : .NET Core 6.0.5 (CoreCLR 6.0.522.21309, CoreFX 6.0.522.21309), X64 RyuJIT
Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|
ToByteArrayNormal | 4.058 ns | 0.0360 ns | 0.0319 ns | 0.0064 | - | - | 40 B |
ToByteArrayIn | 3.690 ns | 0.0350 ns | 0.0327 ns | 0.0064 | - | - | 40 B |
.NET5では通常の引数でもin
引数でもパフォーマンスに差がありませんが、.NET6では1割ほど改善されています。
うれしい改善ですね。これからはin
引数で渡していきましょう。
Discussion