Is there a way to make the C# compiler optimize my OR clauses in an if statement?
For example:
if(Function_that_returns_boolean() || boolean_value)
{
// Do something here...
}
Could have hugely different execution times than
if(boolean_value || Function_that_returns_boolean())
{
// Do something here...
}
depending on how much work Function_that_returns_boolean() actually does internally.
It's unlikely (and perhaps impossible) that the compiler could know exactly how efficient Function_that_returns_boolean() is, and all of my (brief) testing indicates OR statements are always processed left to right, even under using the most aggressive compiler optimizations.
Is this already handled by the compiler (i.e. am I mistaken)? If not, are there any hints I can give to it?
Maybe something like an Attribute that lets the compiler know that it's free to rearrange my code (and if not present, to leave it be)?
[OrStatementUsage(Speed.Fast)] // Always push statement left when possible
public bool Fast_function_that_returns_boolean()
{
return a + b == c; // fast
}
[OrStatementUsage(Speed.Slow)] // Always push statement right when possible
public bool Slow_function_that_returns_boolean()
{
Thread.Sleep(1000);
return a + b == c; // slow
}
(Note: all methods in the statement would have to be tagged and side-effect free to be candidates for rearrangement)
http://msdn.microsoft.com/en-us/library/6373h346.aspx
The conditional-OR operator (||) performs a logical-OR of its bool operands. If the first operand evaluates to true, the second operand isn't evaluated. If the first operand evaluates to false, the second operator determines whether the OR expression as a whole evaluates to true or false.
The first operand will always be evaluated. This is a very important guarantee:
if (obj == null || obj.foo == "bar")
If the compiler could reorder the conditions here, it would change the functionality of the program.
The compiler can't know whether a given reordering would affect the result -- both because it can't in general know what the result will be and because it doesn't know what parts of the result are important. Maybe you want a long delay, or the first calculation does something important for the correctness of the program.
No, the first argument is evaluated, and if it is true, the second argument is not evaluated at all. It is called "short-circuit" evaluation.
See http://msdn.microsoft.com/en-us/library/6373h346.aspx.
There is no way to instruct the compiler to evaluate the second argument of || first.
No, boolean logic operators are always short-circuit evaluated. In case of an or, the second part might not even be evaluated if it already evaluated to true. For instance:
if(ReturnTrue() || SlowOperation()) { /* ... */ }
Assuming that ReturnTrue() returns true, SlowOperation() is never called. The compiler cannot make optimization based on some arbitrary assumptions
Related
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Will all methods in a logical expressions be executed?
Let me explain: let's say we have theese two codes:
foreach(Object o in Objs)
if(o is Class1 || o is Class2)
DoSomething();
__
foreach(Object o in Objs)
if(o is Class1)
DoSomething();
else if(o is Class2)
DoSomething();
Now, of course an OR is better in this case, but my question is different and just out of curiosity: when in the first case o is of type Class1, does the compiler stop and run the code or it checks what comes next anyway?
It would do that in the second case.
|| is short-circuiting, which means: if the first argument returns true, the second argument is not evaluated. In this way, yes it is broadly equivalent to your second example, but more terse.
MSDN Documentation for the || operator in C#
The conditional-OR operator (||) performs a logical-OR of its bool operands. If the first operand evaluates to true, the second operand isn't evaluated. If the first operand evaluates to false, the second operator determines whether the OR expression as a whole evaluates to true or false.
Note: That is also the case for all C-like languages (C, C++, Java, C#) that I know of.
In the operation x || y, y is evaluated only if x is false.
Yes.
The double pipe or "||" will look from the left to the right if some condition is true, whether it will stop looking for other condition and execute the piece of code. The simple pipe or "|" will do the same thing but will check all the conditions (so generally you will prefer using "||").
I came across some statements while surfing the .net source:
If( null != name)
If( false == check())
what is the difference between (name != null) and (Check() == false) statements from the above statements?
Can any one get me clear of this? Please.
I'm sure this is a duplicate, but I can't find it right now.
Code with the constant first is usually written by developers with an (old) background in C, where you might write this:
if (NULL == x)
instead of this:
if (x == NULL)
just in case you made a typo like this:
if (x = NULL) // Valid, but doesn't do what you want.
In most cases in C#, you don't need to do this - because the condition in an if statement has to be convertible to bool.
It would make a difference when you're comparing to a Boolean constant:
if ((Check() = false) // Eek!
... which is one reason to just write:
if (!Check())
Basically, putting the variable first is generally more readable - and in C# the reason for putting the constant first is almost never applicable anyway. (Modern C and C++ compilers will usually give you a warning anyway, so it's no longer a great idea in those languages either, as far as I'm aware...)
In terms of the order of evaluation, there is a theoretical difference in that the left-hand operand will be evaluated before the right-hand operand... but as the constants null and false don't have any side-effects, there's no real difference.
I think this style comes with C/C++ background, where the operator = which can also be used inside if statement, which could be used for comparison as well as assignment.
The statement
if( null != name) is same as if(name != null), so as the other statement
To safeguard from mistakenly assigning the value to the left hand side, this style of check is used in C/C++,
Take a look Coding Horror Yoda Conditions
Using if(constant == variable) instead of if(variable == constant),
like if(4 == foo). Because it's like saying "if blue is the sky" or
"if tall is the man".
The odd reversal looks like it was written by a C/C++ programmer... basically, in C/C++, if you accidentally type:
if(name = null)
instead of
if(name == null)
then that compiles and changes the value to null when invoked. A C/C++ habit to avoid this mistake is to use a constant such as null / false always on the left. This is because you can't reassign a constant, so it generates a compiler error if you use = instead of ==. In C# it (if(a = null)) doesn't usually compile, so that is not a concern.
There is no difference re the position here - both sides are evaluated. Idiomatic C# for this would be simply:
if(name != null) ...
if(!check()) ...
Well I have been reading quite a lot sources but they differ in definiton:
&& is logical operator of logical
conjunction //I guess this is correct
&& is operator of logical AND //I
think this is not precise from
technical point of view
&& is
conditional operator performing
logical AND //I think this is right
as well
While all are correct in terms of understanding, I would say the first one is most precise. Or am I mistaken?
In C#, Java, C++, C, and probably several other languages, && is a programming language implementation of the boolean AND operator. It is designed to account for the following facts (that do not apply in pure propositional logic):
Evaluating an operand may be computationally expensive
Evaluating an operand may fail with an exception
Evaluating an operand may enter an infinite loop
So a boolean expression in a programming language really has four possible outcomes: true, false, "exception", and "infinite loop". In some situations, one has two boolean expressions where the possible success of the second expression can be determined by looking at the first expression. For instance, with the expressions foo != null and foo.bar == 42, we can be certain that if the first expression is false, then the second expression will fail. Hence, the && operator is designed to be "short-cirquited": If the left operand evaluates to false, the right operand is not evaluated. In all cases where both operands would evaluate successfully to true or false, this rule produces the same result as if one actually had evaluated both operands, but it allows for increased performance (because the right operand might not need to be evaluated at all) and increased compactness without sacrificing safety (if one takes care to structure the expression such that the left operand "guards" the right one). Similarly, || will not evaluate the right operand if the left operand evaluates to true.
A shorter answer is that although && is strongly inspired by AND, it is designed to take certain programming peculiarities into account, and a && b should perhaps rather be phrased as "an expression that returns false if a is false, and the value of b if a is true".
The easy answer.
It performs an AND operation on 2 logical expressions returnting a Boolean. It does not evaluate the second if the first is false.
To evaluate both regardless use &.
The complicated answer.
http://www.ecma-international.org/publications/standards/Ecma-334.htm heading 12.3.3.23 seems most relavent.
I find myself unqualified to criticise the definition within.
12.3.3.23 && expressions
For an expression expr of the form expr-first && expr-second:
• The definite assignment state of v before expr-first is the same as the definite assignment state of v before expr.
• The definite assignment state of v before expr-second is definitely assigned if the state of v after exprfirst is either definitely assigned or “definitely assigned after true expression”. Otherwise, it is notdefinitely assigned.
• The definite assignment state of v after expr is determined by:
o If the state of v after expr-first is definitely assigned, then the state of v after expr is definitely assigned.
o Otherwise, if the state of v after expr-second is definitely assigned, and the state of v after expr-first is “definitely assigned after false expression”, then the state of v after expr is definitely assigned.
o Otherwise, if the state of v after expr-second is definitely assigned or “definitely assigned after true expression”, then the state of v after expr is “definitely assigned after true expression”.
o Otherwise, if the state of v after expr-first is “definitely assigned after false expression”, and the state of v after expr-second is “definitely assigned after false expression”, then the state of v after expr is “definitely assigned after false expression”.
o Otherwise, the state of v after expr is not definitely assigned.
[Example: In the following code
class A
{
static void F(int x, int y) {
int i;
if (x >= 0 && (i = y) >= 0) {
// i definitely assigned
}
else {
// i not definitely assigned
}
// i not definitely assigned
}
}
the variable i is considered definitely assigned in one of the embedded statements of an if statement but not in the other. In the if statement in method F, the variable i is definitely assigned in the first embedded statement because execution of the expression (i = y) always precedes execution of this embedded statement. In contrast, the variable i is not definitely assigned in the second embedded statement, since x >= 0 might have tested false, resulting in the variable i’s being unassigned. end example]
I hope that clears things up.
Conjunction is another word for "and". So they're all correct in terms of their output.
In terms of how they actually give the output, && usually doesn't evaluate the second argument if the first one is false.
I discovered a very puzzling behavior for the following code:
public double ReturnBehavior(List<double> ptList)
{
return ptList.Count==0? 0:ptList[0];
}
I thought it should be equivalent to
public double ReturnBehavior(List<double> ptList)
{
if(ptList.Count==0)
return 0;
return ptList[0];
}
But it is not, because the first method will evaluate both true and false condition together. So this means that first method will try an IndexOutOfRange exception if ptList.Count==0.
Am I missing something here? Or is it a bug in vs 2008?
I've checked both in VS2010 and VS2008, behavior is expected - no exceptions. If you have errors - they are not in the given code fragment
They ought to behave the same. The ternary operator uses short-circuit semantics. If the test passes, only the first expression is evaluated, otherwise, only the second expression is evaluated. Are you actually seeing an exception?
I think that in some cases, if you have a multicore processor, the compiler will tell the processor to evaluate ahead if possible. At least i know that's the case when for example i have an if(condition1 && condition2), on some computers it will evaluate both conditions in parallel, and this means it evaluates the second condition even if the first fails.
This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
== Operator and operands
Possible Duplicates:
Is there any difference between if(a==5) or if(5==a) in C#?
== Operator and operands
Ok, this may be stupid question, but searching in google (cant seem to ACTUALLY search for an exact phrase even with quotes)
What if any difference is there between
if(false == <somecondition>){
and
if(<somecondition> == false){
in C#? I am familiar with c#'s expression evalution, and understand how the order would make sense if you were doing something like:
if(AccountIsInvalid || AccountIsUnregistered)
I dont need a huge lesson, but would like to understand why some people prefer to do things with false==.... route.
Personally, I never compare anything to false or true.
I would go with:
if (!somecondition)
or:
if (somecondition)
In C there would have been, perhaps, some reason to do this as you could easily make a mistake and use the assignment operator instead of the comparison operator, but in C# it shouldn't make any difference -- you'll get a compile warning if you use the assignment operator. If the assignment were a different type (say int), it would result in an error, since the result wouldn't be a legal expression for the if statement.
I would prefer it to be
if (!<somecondition>)
{
...
}
rather than a comparison to false (or true, for that matter).
Before performing any optimizations or short-circuits, the compiler needs to resolve <somecondition> to true or false value, thus there is no reason why the compiler would evaluate the expressions <somecondition> == false and false == <somecondition> any differently.
This must surely be an issue of style, and style only.
This doesn't matter in C# like it does in c/c++ because conditions must evaluate to a boolean.