外观顺序是否在具有多个条件的单个IF语句中很重要

时间:2013-10-15 19:43:18

标签: c# .net winforms performance

我有一个最多 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次。一个先测试了Contains,另一个先测试了Bool。重复这两个循环10次,看起来布尔值首先平均每20K迭代半毫秒。首先评估的Contains每20K迭代大约需要3毫秒。确实有点小差异!

4 个答案:

答案 0 :(得分:5)

给定的布尔表达式将从左到右,而不是从右到左进行计算。订单确实已定义;它不是任意的,也不是优化的。它总是从左到右。

这在规范中特别指出,因此每个表达式的副作用总是按照定义的顺序执行。

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

答案 1 :(得分:2)

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

答案 2 :(得分:2)

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

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

你的第二种方法会更快

答案 3 :(得分:1)

在此示例中,您使用&&评估short-circuiting

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
}

老实说,我不认为明显 比其他人快。哦,另外,评价是从左到右,从不从右到左。