C# 用于性能优化的if语句分析

C# 用于性能优化的if语句分析,c#,if-statement,C#,If Statement,在c语言中,所有的if语句都是在执行之前分析的,所以如果在证明之前if语句不能为真,所有的条件都会被取消吗 我的问题是,我想去掉多个if语句,因为if语句中的一些方法需要很长时间才能执行,如果执行它们,这是浪费时间的 这里有一个简单的if语句,它是有效的。但这对复杂的if语句有多好 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading

在c语言中,所有的if语句都是在执行之前分析的,所以如果在证明之前if语句不能为真,所有的条件都会被取消吗

我的问题是,我想去掉多个if语句,因为if语句中的一些方法需要很长时间才能执行,如果执行它们,这是浪费时间的

这里有一个简单的if语句,它是有效的。但这对复杂的if语句有多好

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace IfTest
{
    class Program
    {
        static void Main(string[] args)
        {
            if (true || NeedALongTime())
            {
                Console.WriteLine("!");
            }

            Console.ReadLine();
        }

        private static bool NeedALongTime()
        {
            Thread.Sleep(10000);

            return true;
        }
    }
}
NeedALongTime方法将永远不会被调用。一旦能够确定结果,C将停止计算逻辑表达式

这称为短路,与任何类型的分析无关。这是语言计算逻辑表达式的方式。若使用返回true而不是true值的方法,则短路仍然有效,并且不会调用NeedALongTime

语言如C和C++使用短路,而其他语言,如VB.NET不使用。 使用短路时应小心。虽然对表达式进行排序以使最有可能的情况首先出现是一种好的做法,但在某些情况下,在表达式中插入短路标志只是为了提高性能,这是一种非常糟糕的做法

对于这样的条件语句,最好使用不同的if语句。生成的IL代码将是相同的,但代码将更加清晰


如果在执行方法之前需要检查多个条件,或者有多个重方法的条件,最好在代码开始时将它们捆绑起来,甚至将条件检查提取到单独的函数中。这样可以避免将保护条件与实际业务逻辑混淆

布尔运算符&&and | |的评估模型定义良好。仅当无法从第一个操作数派生答案时,才计算第二个操作数

这叫做短路。这是有保证的行为

这不是编译器或JIT的优化


您可以信赖这一点,但在我看来,出于性能原因,这样做会导致脆弱且容易出错的代码。对于未来的维护人员来说,虽然没有明显的依赖关系,但是为什么评估的顺序必须是这样,这可能并不明显。也许你可以用Lazy来得到Lazy评估

不,它们不都是针对带有&&和| | Google about short-circuit的布尔表达式计算的。这就是为什么如果obj!=null&&obj.Value==someValue。此外,如果表达式可以确定,并且在编译时是常量,那么编译器本身可能会在发布模式下进行优化,从而将代码删除,但您也应该收到一条警告。作为一般性的声明,处理性能的最佳方法是编写清晰、经过深思熟虑的代码并设定性能目标。然后,你衡量你所写内容的表现,如果它足够好,你就继续下一个任务。通过创建一个关于“我应该编写所有if语句”的数千条规则的列表,您无法编写性能良好的代码,例如,它已经以这种方式工作,整个if语句被删除,只有对Console.WriteLine的调用仍然存在。当然,你永远不会注意到它的运行速度快了一纳秒。第五颗子弹。谢谢你,非常有趣。谢谢你的回答。一个问题是:C语言和C++语言都使用短路,而其他语言,比如VB.NET不使用。我认为.net框架可以完成这项工作,而不是一般的C/VB.net。不,每种语言都使用自己的语义。你可以说CPU做这项工作,但这也不是真的。布尔表达式只有两个参数。复杂逻辑表达式是按特定语言定义的顺序和语义计算的布尔表达式的组合。我不同意你的观点。使用短路时应小心。当我编写C代码时,我不关心其他语言,在C中,短路是一种很好的方法,可以将执行逻辑与条件本身结合起来,以避免if树。举个例子,如果checka | | CheckB&&CheckC DoSomething;,那么很容易理解;,你知道,什么是CheckA属性设置程序代码或方法总是会出现,但CheckB只有在CheckA失败时才会出现,CheckC只有在CheckB不会失败时才会出现,但CheckA和DoSomething调用和调用逻辑并没有模糊。我不认为你不同意。问题在于编写代码,比如if CheckA | | DoSomething{LogSomething;}。我确实写道,支票应该捆绑在一起,但实际操作应该分开。我没有写你应该考虑VB.NET或者你根本不应该使用短路。谢谢你,只是作为一个信息,NeedALongTime不做任何操作。“这只是证明了一件事。”BendEg接着,我将详细说明:您可以为可能需要运行的每一个昂贵的计算设置一个惰性。它们可以相互引用,从而形成依赖项的DAG。这样你就可以写你的if语句了 以及其他自动最大程度延迟的计算。