在具有多个条件的单个 IF 语句中,出现顺序是否重要

本文关键字:顺序 是否 语句 IF 条件 单个 | 更新日期: 2023-09-27 18:35:25

我有一个集合,其中包含多达 19,000 个条目,我正在 foreach 语句中迭代这些条目。在 foreach 开始时,我检查字符串是否包含 2 个单词中的 1 个和一个布尔值,然后我要么继续,要么执行更多操作。

        foreach (SvnStatusEventArgs e in results) //results being my Collection
        {
            if ((e.Path.Contains("bin") || 
                e.Path.Contains("obj")) && !includeBinObjFolders)
                continue;
            //Do a bunch of things
        }

我不确定计算机是否会检查字符串中的"bin"或"obj",然后检查布尔值,也许它会意识到字符串包含这两个"关键字"之一并不重要。

基本上我想我要

说的是以下内容需要不同的时间来运行吗?

        foreach (SvnStatusEventArgs e in results) //results being my Collection
        {
            if (!includeBinObjFolders && 
                    (e.Path.Contains("bin") || 
                     e.Path.Contains("obj")
                     )
                )
                continue;
            //Do a bunch of things
        }

出于某种原因,我听到一个声音在我脑后告诉我,它首先评估最右边的表情,然后向左工作。如果是这样,第一个应该更有效率吧?我没有一种简单的方法来测试大于 ~200 个文件的集合,因此简单地使用计时器会产生如此接近的结果,我无法确认一种方法是否更好。

坦率地说,我认为最终用户不太可能在此集合中遇到最多 500 多条数据,但理论上它可能由于用户错误而发生。

编辑谢谢大家。在这里发布之前,我尝试搜索,但我忘记了逻辑方面的"短路"一词,所以我很难在这里找到与我冗长的标题相关的答案。

编辑 2 实际上,我只是创建了一个小型控制台应用程序,该应用程序有一个 2 for 循环,每个循环迭代 20,000 次。一个首先测试了包含,另一个首先测试了布尔值。将这两个循环重复 10 次,看起来布尔值第一次平均每 20K 次迭代需要半毫秒。首先评估的包含大约需要每 20K 次迭代 3 毫秒。确实有一点不同!

在具有多个条件的单个 IF 语句中,出现顺序是否重要

给定的布尔表达式将从左到右计算,而不是从右到左计算。 顺序确实是确定的;它不是任意的,也不能优化。 它将始终从左到右。

这在规范中被特别指出,以便每个表达式的副作用始终按定义的顺序执行。

如果需要,您可以将布尔变量移到前面作为优化。 这可能不是一个巨大的优化,所以不要太担心它,但它是一个优化。(当然,除非您知道它将始终或几乎总是解析为true而另一个表达式将解析为 false。

最后一个表达式可能会在运行时节省更多时间,因为您只是先计算布尔值。如果这是假的,最右边的表达式甚至不会被计算,因为假和任何东西都是假的。

逻辑运算符从左到右处理,&&||是短路运算符;含义

x || y // will evaluate x and if it's false, then it will evaluate y
x && y // will evaluate x and if it's true, then it will evaluate y

http://msdn.microsoft.com/en-us/library/aa691310(v=vs.71).aspx

您的第二种方法会更快

在此示例中,您使用 && 缩短评估

foreach (SvnStatusEventArgs e in results) //results being my Collection
{
   if (!includeBinObjFolders && 
      (e.Path.Contains("bin") || 
       e.Path.Contains("obj")))
       continue;
   //Do a bunch of things
}

所以基本上,如果!includeBinObjFolders = true停止评估。

在此示例中,您使用||来评估前两个条件;如果其中一个条件true您将停止评估。

foreach (SvnStatusEventArgs e in results) //results being my Collection
{
   if ((e.Path.Contains("bin") || 
      e.Path.Contains("obj")) && !includeBinObjFolders)
      continue;
      //Do a bunch of things
}

老实说,我不认为任何一个会明显比另一个快。 哦,顺便说一句,评估是从左到右的,而不是从右到左的。