2

I've got a Collection with up to 19,000 entries in it that I'm iterating over in a foreach statement. At the beginning of the foreach, I check if a string contains 1 of 2 words and a boolean value, then I either continue or perform some more operations.

        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
        }

I wasn't sure if the computer would check the string for either "bin" or "obj", and then check the boolean and maybe it'd realize it didn't matter that the strings contained one of those two 'key words'.

Basically I guess what I'm saying is would the following take a different amount of time to run?

        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
        }

For some reason, I hear a voice in the back of my head telling me that it evaluates the right-most expression first, and works its way left. If so, the first should be more efficient right? I don't have an easy way of testing a collection larger than ~200 files so simply using a timer yields results that are so close I can't confirm if one way is better.

Frankly I think it's highly unlikely end users will encounter more than 500 pieces of data in this collection at most, but theoretically it could happen due to user error.

Edit thanks everyone. I tried searching around before posting here but I forgot the term "short circuiting" in regards to logic so I was having a tough time finding an answer relevant to my wordy title here.

Edit 2 Actually I just went and created a small console application that had a 2 for loops iterating 20,000 times each. One tested the Contains first, the other tested the Bool first. Repeating these two loops 10 times over, it looks like the boolean first takes on average half of a millisecond per 20K iterations. The Contains being evaluated first takes roughly 3 milliseconds per 20K iterations. A small difference indeed!

4

4 回答 4

5

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

这在规范中特别提到,以便每个表达式的副作用总是以定义的顺序执行。

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

于 2013-10-15T19:46:37.250 回答
2

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

于 2013-10-15T19:46:16.593 回答
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

你的第二种方法会更快

于 2013-10-15T19:49:34.280 回答
1

在此示例中,您正在使用以下方法短路评估&&

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
}

老实说,我认为两者都不会比另一个快得多哦,顺便说一句,评估是从左到右的,而不是从右到左的。

于 2013-10-15T19:53:25.447 回答