如何在 C# 中计算方法的时间

本文关键字:方法 时间 计算 | 更新日期: 2023-09-27 18:33:53

例如,

我如何计算 3 种方法的时间,但这只是我需要时间的第一种方法和最后一种方法。我不需要中间方法的时间。例如,方法一需要 200 毫秒,方法二需要 500 毫秒,方法三需要 300 毫秒。总时间:1000 毫秒,但应为 1000 毫秒 – 500 毫秒(方法二)= 500 毫秒。

有没有软件可以做到这一点?或者如何更改我的代码以使其正常工作?

static void Main(string[] args)
{
  Console.WriteLine("============================");
  Console.WriteLine("        Performance         ");
  Console.WriteLine("============================'n");
  Console.WriteLine("Total time: {0}", TimeTaking(MethodOne).TotalMilliseconds.ToString());
  Console.ReadKey();
}
static TimeSpan TimeTaking(Action methodName)
{
  Stopwatch stopwatch = Stopwatch.StartNew();
  methodName();
  stopwatch.Stop();
  return stopwatch.Elapsed;
}
static void MethodOne()
{
  Thread.Sleep(200);
  MethodTwo();
}
static void MethodTwo()
{
  // Stop TimeTaking
  Thread.Sleep(500);
  MethodThree();
}
static void MethodThree()
{ 
  // continue TimeTaking
  Thread.Sleep(300); 
}

如何在 C# 中计算方法的时间

如果线程安全不是问题,则可以将Stopwatch放在TimeTaking方法之外。这允许您在所需的位置(方法的开头或结尾)调用Stop()Start()

当然,您可以将Stopwatch作为参数传递。或者让所有内容返回一个包含运行所花费毫秒数的 int/long。这两种解决方案都非常丑陋,因为它要么添加一个额外的参数,要么强制out参数,以防您确实想要返回有用的值。

如果没有单独的分析工具,则必须在 MethodOneMethodThree 内使用Stopwatch手动测量时间。没有办法自动执行此操作。

这里有很多选项...

您在操作中使用秒表来了解这些方法的持续时间。当然,这是重复的代码(即使您将实际的秒表逻辑代码放在单独的方法中),但可能足以满足您的需求。

或者,您可以将 AOP 与 PostSharp 一起使用来执行此操作,如果您在所有方法中都需要此行为,则可以避免重复的代码。但是你必须以更加模块化的方式组织你的代码(这使得它也更易于测试):

[LogExecutionTimeAttribute]
void MethodOne()
{
   Thread.Sleep(200);     
}
void MethodTwo()
{      
   Thread.Sleep(500);
}
[LogExecutionTimeAttribute]
void MethodThree()
{ 
   Thread.Sleep(300); 
}
void StartFlow()
{
   MethodOne();
   MethodTwo();
   MethodThree();
}

(不知道为什么需要它们是静态的,应该避免)

最后,但对你来说可能有点矫枉过正,像AppDynamics这样的APM工具也可以做到这一点。

我写了这一小段代码来做一些简单的测量:

   public class Timer : IDisposable
   {
        private readonly Stopwatch _stopwatch;
        private readonly Action<TimeSpan> _finishedDelegate;
        private Timer(Action<TimeSpan> finishedDelegate)
        {
            if (finishedDelegate == null)
            {
                finishedDelegate = timeSpan => Debug.Print("Elapsed time: {0}", timeSpan);
            }
            _finishedDelegate = finishedDelegate;
            _stopwatch = Stopwatch.StartNew();
        }
        public static Timer Start(Action<TimeSpan> finishedDelegate = null)
        {
            return new Timer(finishedDelegate);
        }
        public void Dispose()
        {
            _stopwatch.Stop();
            _finishedDelegate.Invoke(_stopwatch.Elapsed);
        }
   }

像这样使用:

using (Timer.Start())
{
   // Code to be measured here
}

可以在 Start 方法中提供一个委托来控制结果应发生的情况。默认情况下,它将时间输出到调试控制台。