1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Qiita100万記事感謝祭!記事投稿キャンペーン開催のお知らせ

C# メソッドの実行時間・処理時間を測定する

Last updated at Posted at 2025-01-14

概要

C# であるメソッドの実行時間・処理時間を測定する処理をよく書くので、備忘録としてメモを残しておきます。

簡易コード
using System.Diagnostics;
public static (TResult result, TimeSpan elapsed) MeasureExecutionTime<TResult>(Func<TResult> method)
{
    var stopwatch = Stopwatch.StartNew();
    TResult result = method();
    stopwatch.Stop();
    return (result, stopwatch.Elapsed);
}

試行錯誤してこの形になりました。

コード全文

MethodTimer.cs
// These codes are licensed under CC0. (権利放棄、自由利用可)
//https://creativecommons.org/publicdomain/zero/1.0/deed.ja
using System.Diagnostics;

namespace MethodTimer;

/// <summary>
/// メソッドの実行時間を測定するためのユーティリティクラス
/// </summary>
public static class MethodTimer
{
    /// <summary>
    /// 戻り値のあるメソッドの実行時間を測定
    /// </summary>
    /// <typeparam name="TResult">メソッドの戻り値の型</typeparam>
    /// <param name="method">実行時間を測定する対象のメソッド</param>
    /// <returns>
    /// <list type="bullet">
    /// <item><description>result: メソッドの実行結果</description></item>
    /// <item><description>elapsed: 実行にかかった時間</description></item>
    /// </list>
    /// </returns>
    /// <example>
    /// 戻り値のあるメソッドの実行時間を測定する例
    /// <code>
    /// var (result, elapsed) = MethodTimer.MeasureExecutionTime(() => SomeMethod());
    /// Console.WriteLine($"Result: {result}, Elapsed Time: {elapsed.TotalMilliseconds} ms");
    /// </code>
    /// </example>
    public static (TResult result, TimeSpan elapsed) MeasureExecutionTime<TResult>(Func<TResult> method)
    {
        var stopwatch = Stopwatch.StartNew();
        TResult result = method();
        stopwatch.Stop();
        return (result, stopwatch.Elapsed);
    }

    /// <summary>
    /// 戻り値のないメソッドの実行時間を測定
    /// </summary>
    /// <param name="method">実行時間を測定する対象のメソッド</param>
    /// <returns>実行にかかった時間</returns>
    /// <example>
    /// 戻り値のないメソッドの実行時間を測定する例
    /// <code>
    /// var elapsed = MethodTimer.MeasureExecutionTime(() => SomeVoidMethod());
    /// Console.WriteLine($"Elapsed Time: {elapsed.TotalMilliseconds} ms");
    /// </code>
    /// </example>
    public static TimeSpan MeasureExecutionTime(Action method)
    {
        var stopwatch = Stopwatch.StartNew();
        method();
        stopwatch.Stop();
        return stopwatch.Elapsed;
    }

    /// <summary>
    /// 戻り値のあるメソッドの実行時間を測定し、結果をコンソールに出力
    /// </summary>
    /// <typeparam name="TResult">メソッドの戻り値の型</typeparam>
    /// <param name="method">実行時間を測定する対象のメソッド</param>
    /// <returns>メソッドの実行結果</returns>
    /// <example>
    /// 戻り値のあるメソッドの実行時間を測定してログに出力する例
    /// <code>
    /// var result = MethodTimer.LogExecutionTime(() => SomeMethod());
    /// </code>
    /// </example>
    public static TResult LogExecutionTime<TResult>(Func<TResult> method)
    {
        var stopwatch = Stopwatch.StartNew();
        TResult result = method();
        stopwatch.Stop();
        Console.WriteLine($"Result: {result}, Elapsed Time: {stopwatch.Elapsed.TotalMilliseconds} ms");
        return result;
    }

    /// <summary>
    /// 戻り値のないメソッドの実行時間を測定し、結果をコンソールに出力
    /// </summary>
    /// <param name="method">実行時間を測定する対象のメソッド</param>
    /// <example>
    /// 戻り値のないメソッドの実行時間を測定してログに出力する例
    /// <code>
    /// MethodTimer.LogExecutionTime(() => SomeVoidMethod());
    /// </code>
    /// </example>
    public static void LogExecutionTime(Action method)
    {
        var stopwatch = Stopwatch.StartNew();
        method();
        stopwatch.Stop();
        Console.WriteLine($"Elapsed Time: {stopwatch.Elapsed.TotalMilliseconds} ms");
    }
}

使用例

Program.cs
using static MethodTimer.MethodTimer;

class Program
{
    private static void Main()
    {
        //使用例
        var fuga = new FugaClass();
        var piyo = new PiyoClass { Value = "Hello" };

        // 戻り値あり、引数あり
        var (result0, elapsed0) = MeasureExecutionTime(() => fuga.FugaMethod(piyo));
        Console.WriteLine($"Result: {result0.Value}, Elapsed Time (result, arg): {elapsed0.TotalMilliseconds} ms");
        Console.WriteLine();

        // 戻り値なし、引数あり
        var elapsed1 = MeasureExecutionTime(() => fuga.FugaMethodVoid(piyo));
        Console.WriteLine($"Elapsed Time (void, arg): {elapsed1.TotalMilliseconds} ms");
        Console.WriteLine();

        // 戻り値あり、引数なし
        var (result2, elapsed2) = MeasureExecutionTime(fuga.FugaMethodString);
        Console.WriteLine($"Result: {result2}, Elapsed Time (result, no arg): {elapsed2.TotalMilliseconds} ms");
        Console.WriteLine();

        // 戻り値なし、引数なし
        var elapsed3 = MeasureExecutionTime(fuga.FugaMethodVoid);
        Console.WriteLine($"Elapsed Time (void, no arg): {elapsed3.TotalMilliseconds} ms");
        Console.WriteLine();

        //コンソールに実行時間を出力
        //戻り値あり、引数あり
        HogeClass? result3 = LogExecutionTime(() => fuga.FugaMethod(piyo));
        Console.WriteLine($"Result: {result3.Value}");

        //戻り値なし、引数あり
        LogExecutionTime(() => fuga.FugaMethodVoid(piyo));
        Console.WriteLine();

        //戻り値あり、引数なし
        string? result5 = LogExecutionTime(fuga.FugaMethodString);
        Console.WriteLine($"Result: {result5}");
        Console.WriteLine();
        //戻り値なし、引数なし
        LogExecutionTime(fuga.FugaMethodVoid);
        Console.WriteLine();
    }
}

public class HogeClass
{
    public int Value { get; set; }
}

public class FugaClass
{
    public HogeClass FugaMethod(PiyoClass arg)
    {
        Thread.Sleep(400); // ダミー処理
        Console.WriteLine($"FugaMethod executed with arg: {arg.Value}");
        return new HogeClass() { Value = 0xff };
    }

    public void FugaMethodVoid(PiyoClass arg)
    {
        Thread.Sleep(300); // ダミー処理
        Console.WriteLine($"FugaMethodVoid executed with arg: {arg.Value}");
    }

    public string FugaMethodString()
    {
        Thread.Sleep(200); // ダミー処理
        return "Hello, World! by FugaMethodString";
    }

    public void FugaMethodVoid()
    {
        Thread.Sleep(100); // ダミー処理
        Console.WriteLine("Void method with no arguments executed");
    }
}

public class PiyoClass
{
    public string Value { get; set; }
}

実行結果

実行結果
FugaMethod executed with arg: Hello
Result: 255, Elapsed Time (result, arg): 428.6967 ms

FugaMethodVoid executed with arg: Hello
Elapsed Time (void, arg): 316.5747 ms

Result: Hello, World! by FugaMethodString, Elapsed Time (result, no arg): 212.1155 ms

Void method with no arguments executed
Elapsed Time (void, no arg): 105.722 ms

FugaMethod executed with arg: Hello
Result: HogeClass, Elapsed Time: 401.6136 ms
Result: 255
FugaMethodVoid executed with arg: Hello
Elapsed Time: 307.6023 ms

Result: Hello, World! by FugaMethodString, Elapsed Time: 214.6779 ms
Result: Hello, World! by FugaMethodString

Void method with no arguments executed
Elapsed Time: 107.0708 ms

使用環境

Visual Studio 2022
.NET 9.0 / C# バージョン 13.0

参考資料

Stopwatch クラス (System.Diagnostics) | Microsoft Learn

ラムダ式 - ラムダ式と匿名関数 - C# reference | Microsoft Learn

Func Delegate (System) | Microsoft Learn

デリゲート - C# によるプログラミング入門 | ++C++; // 未確認飛行 C

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?