rksoftware

Visual Studio とか C# とかが好きです

メソッドの引数の型違いでパフォーマンス計測

C# の引数の型が違うメソッドを用意してパフォーマンス計測をしてみます。

計測には BenchmarkDotNet ( NuGet Gallery | BenchmarkDotNet 0.13.11 ) を使用してみました。

■ 検証対象コード

引数違いで 3 つのメソッドを用意してみました。object 型のものと、int 型のものと、string 型のものです。

namespace ClassLibrary1
{
    public static class MethodExtensions
    {
        public static int ExtensionMethod(this object s) => 0;
        public static int ExtensionMethod(this int s) => 0;
        public static int ExtensionMethod(this string s) => 0;
    }
}

BenchmarkDotNet を使った計測コードです。

using ClassLibrary1;

BenchmarkDotNet.Running.BenchmarkRunner.Run<Sample>(new BenchmarkDotNet.Configs.DebugInProcessConfig());

public class Sample
{
    object o = new object();
    int i = 0;
    string s = "";
    [BenchmarkDotNet.Attributes.Benchmark]
    public void MethodObject() => o.ExtensionMethod();
    [BenchmarkDotNet.Attributes.Benchmark]
    public void MethodInt() => i.ExtensionMethod();
    [BenchmarkDotNet.Attributes.Benchmark]
    public void MethodString() => s.ExtensionMethod();
}

■ 計測結果

計測結果です。2 回実行してみました。

Method Mean Error StdDev Median
MethodObject 0.0442 ns 0.0351 ns 0.0667 ns 0.0000 ns
MethodInt 0.0311 ns 0.0278 ns 0.0522 ns 0.0000 ns
MethodString 0.0259 ns 0.0290 ns 0.0377 ns 0.0032 ns

Method Mean Error StdDev Median
MethodObject 0.0430 ns 0.0344 ns 0.0593 ns 0.0173 ns
MethodInt 0.0516 ns 0.0379 ns 0.0703 ns 0.0144 ns
MethodString 0.2225 ns 0.0492 ns 0.0874 ns 0.2031 ns

ブレが大きいですね。そもそもが早すぎるのかもしれません。

時間がかかるように、検証メソッドの中でループしてみましょう。

■ 検証対象コード ( short.MaxValue 回ループ )

foreachshort.MaxValue 回ループするようにしてみます。

using ClassLibrary1;

BenchmarkDotNet.Running.BenchmarkRunner.Run<Sample>(new BenchmarkDotNet.Configs.DebugInProcessConfig());

public class Sample
{
    int[] ints = new int[short.MaxValue];
    object o = new object();
    int i = 0;
    string s = "";
    [BenchmarkDotNet.Attributes.Benchmark]
    public void MethodObject() { foreach (var c in ints) o.ExtensionMethod(); }
    [BenchmarkDotNet.Attributes.Benchmark]
    public void MethodInt() { foreach (var c in ints) i.ExtensionMethod(); }
    [BenchmarkDotNet.Attributes.Benchmark]
    public void MethodString() { foreach (var c in ints) s.ExtensionMethod(); }
}

■ 結果

3 回実行してみました。

1 回目

Method Mean Error StdDev
MethodObject 12.68 us 0.248 us 0.372 us
MethodInt 11.73 us 0.207 us 0.262 us
MethodString 11.83 us 0.234 us 0.566 us

2 回目

Method Mean Error StdDev
MethodObject 12.98 us 0.259 us 0.511 us
MethodInt 11.91 us 0.237 us 0.468 us
MethodString 11.69 us 0.220 us 0.235 us

3 回目

Method Mean Error StdDev
MethodObject 12.93 us 0.248 us 0.305 us
MethodInt 11.90 us 0.228 us 0.334 us
MethodString 12.07 us 0.238 us 0.464 us

なんとなく結果が安定した気がします。

object > string > int ( 左ほど遅い ) という順に時間がかかる傾向があるのかもしれません。まったく誤差の範囲ですけれど。