and*_*ecu 5 .net c# performance lambda delegates
请考虑以下代码:
if (IsDebuggingEnabled) {
instance.Log(GetDetailedDebugInfo());
}
Run Code Online (Sandbox Code Playgroud)
GetDetailedDebugInfo() 可能是一种昂贵的方法,所以我们只想在调试模式下运行时调用它.
现在,更清洁的替代方案是编写如下代码:
instance.Log(() => GetDetailedDebugInfo());
Run Code Online (Sandbox Code Playgroud)
其中.Log()的定义如下:
public void Log(Func<string> getMessage)
{
if (IsDebuggingEnabled)
{
LogInternal(getMessage.Invoke());
}
}
Run Code Online (Sandbox Code Playgroud)
我关心的是性能,初步测试没有显示第二种情况特别昂贵,但如果负载增加,我不想遇到任何意外.
哦,请不要建议条件编译,因为它不适用于这种情况.
(PS:我直接在StackOverflow中写了代码问一个问题textarea所以不要责怪我,如果有微妙的错误,它没有编译,你明白了:)
不,它应该没有糟糕的表现.毕竟,只有在性能不是最重要的调试模式下才会调用它.实际上,您可以删除lambda并只传递方法名称以消除不必要的中间匿名方法的开销.
请注意,如果要在Debug版本中执行此操作,可以[Conditional("DEBUG")]向log方法添加属性.
我希望获得一些有关这种情况下性能的文档,但似乎我得到的只是有关如何改进我的代码的建议......似乎没有人读过我的 PS - 没有给你分。
所以我写了一个简单的测试用例:
public static bool IsDebuggingEnabled { get; set; }
static void Main(string[] args)
{
for (int j = 0; j <= 10; j++)
{
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i <= 15000; i++)
{
Log(GetDebugMessage);
if (i % 1000 == 0) IsDebuggingEnabled = !IsDebuggingEnabled;
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}
Console.ReadLine();
for (int j = 0; j <= 10; j++)
{
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i <= 15000; i++)
{
if (IsDebuggingEnabled) GetDebugMessage();
if (i % 1000 == 0) IsDebuggingEnabled = !IsDebuggingEnabled;
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}
Console.ReadLine();
}
public static string GetDebugMessage()
{
StringBuilder sb = new StringBuilder(100);
Random rnd = new Random();
for (int i = 0; i < 100; i++)
{
sb.Append(rnd.Next(100, 150));
}
return sb.ToString();
}
public static void Log(Func<string> getMessage)
{
if (IsDebuggingEnabled)
{
getMessage();
}
}
Run Code Online (Sandbox Code Playgroud)
两个版本之间的时间似乎完全相同。我在第一种情况下得到 145 毫秒,在第二种情况下得到 145 毫秒
看来我回答了我自己的问题。