gpt4 book ai didi

c# - StackFrame 的性能如何?

转载 作者:IT王子 更新时间:2023-10-29 03:57:19 26 4
gpt4 key购买 nike

我正在考虑使用类似 StackFrame stackFrame = new StackFrame(1) 的东西来记录执行方法,但我不知道它对性能的影响。堆栈跟踪是在每次方法调用时构建的东西,所以性能不应该是一个问题,还是它只是在被要求时构建的东西?您是否建议在性能非常重要的应用程序中反对它?如果是这样,是否意味着我应该在发布时禁用它?

最佳答案

编辑:一些背景


我们有一个类似的功能,但 99% 的时间都被禁用;我们使用的方法如下:

public void DoSomething()
{
TraceCall(MethodBase.GetCurrentMethod().Name);
// Do Something
}

public void TraceCall(string methodName)
{
if (!loggingEnabled) { return; }
// Log...
}

TraceCall(MethodBase.GetCurrentMethod().Name)

这很简单,但无论是否启用跟踪,我们都会招致使用反射查找方法名称的性能损失。

我们的选择是要么在每个方法中都需要更多代码(并冒简单错误或拒绝的风险),要么切换到使用 StackFrame 来确定调用方法记录时已启用。

选项 A:

public void DoSomething()
{
if (loggingEnabled)
{
TraceCall(MethodBase.GetCurrentMethod().Name);
}
// Do Something
}

public void TraceCall(string methodName)
{
if (!loggingEnabled) { return; }
// Log...
}

选项 B:

public void DoSomething()
{
TraceCall();
// Do Something
}

public void TraceCall()
{
if (!loggingEnabled) { return; }
StackFrame stackFrame = new StackFrame(1);
// Log...
}

我们选择了选项 B。与选项 A 相比,它提供了显着的性能改进当禁用日志记录时,99% 的时间并且实现起来非常简单。 p>

这里是对 Michael 代码的修改,以显示这种方法的成本/ yield

using System;
using System.Diagnostics;
using System.Reflection;

namespace ConsoleApplication
{
class Program
{
static bool traceCalls;

static void Main(string[] args)
{
Stopwatch sw;

// warm up
for (int i = 0; i < 100000; i++)
{
TraceCall();
}

// call 100K times, tracing *disabled*, passing method name
sw = Stopwatch.StartNew();
traceCalls = false;
for (int i = 0; i < 100000; i++)
{
TraceCall(MethodBase.GetCurrentMethod());
}
sw.Stop();
Console.WriteLine("Tracing Disabled, passing Method Name: {0}ms"
, sw.ElapsedMilliseconds);

// call 100K times, tracing *enabled*, passing method name
sw = Stopwatch.StartNew();
traceCalls = true;
for (int i = 0; i < 100000; i++)
{
TraceCall(MethodBase.GetCurrentMethod());
}
sw.Stop();
Console.WriteLine("Tracing Enabled, passing Method Name: {0}ms"
, sw.ElapsedMilliseconds);

// call 100K times, tracing *disabled*, determining method name
sw = Stopwatch.StartNew();
traceCalls = false;
for (int i = 0; i < 100000; i++)
{
TraceCall();
}
Console.WriteLine("Tracing Disabled, looking up Method Name: {0}ms"
, sw.ElapsedMilliseconds);

// call 100K times, tracing *enabled*, determining method name
sw = Stopwatch.StartNew();
traceCalls = true;
for (int i = 0; i < 100000; i++)
{
TraceCall();
}
Console.WriteLine("Tracing Enabled, looking up Method Name: {0}ms"
, sw.ElapsedMilliseconds);

Console.ReadKey();
}

private static void TraceCall()
{
if (traceCalls)
{
StackFrame stackFrame = new StackFrame(1);
TraceCall(stackFrame.GetMethod().Name);
}
}

private static void TraceCall(MethodBase method)
{
if (traceCalls)
{
TraceCall(method.Name);
}
}

private static void TraceCall(string methodName)
{
// Write to log
}
}
}

结果:

Tracing Disabled, passing Method Name: 294ms
Tracing Enabled, passing Method Name: 298ms
Tracing Disabled, looking up Method Name: 0ms
Tracing Enabled, looking up Method Name: 1230ms

关于c# - StackFrame 的性能如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1348643/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com