Multiple if blocks or single if/else block? - performance

Which will typically have better running time, multiple if blocks or a single if/else block?
if (statement1) {
/* do something */
return result;
}
if (statement2) {
/* do something */
return result;
}
if (statement3) {
/* do something */
return result;
}
Versus:
if (statement1) {
/* do something */
return result;
} else if (statement2) {
/* do something */
return result;
} else if (statement3) {
/* do something */
return result;
}
I've always used the first style when the logical statements weren't in any way related, and the second if they were.
EDIT
To clarify why this thought popped into my head, I am programming a prime checker and have an if block that looks something like this:
if(n<2) return 0;
if(n==2) return 1;
if(n%2==0) return 0;
...

Which will typically have better running time, multiple if blocks or a single if/else block?
This is largely irrelevant as the semantics are different.
Now, if the goal is comparing the case of
if (a) { .. }
else if (b) { .. }
else { .. }
with
if (a) { return }
if (b) { return }
return
where no statements follow the conditional then they are the same and the compiler (in the case of a language like C) can optimize them equivalently.

Always go for if else if... when you know only one of the condition is to be executed, Writing multiple if's will make the compiler to check for each and every condition even when the first condition is met which will have a performance overhead, multiple if's can be used when u want to check and perform multiple operations based on certain condition

The if/else approach is faster, because it will skip evaluating the following conditions after one test succeeds.
However, the two forms are only equivalent if the conditions are mutually exclusive. If you just mindlessly convert one form into the other, you will introduce bugs. Make sure that you get the logic right.

Related

Responsive asynchronous search-as-you-type in Java 8

I'm trying to implement a "search as you type" pattern in Java.
The goal of the design is that no change gets lost but at the same time, the (time consuming) search operation should be able to abort early and try with the updated pattern.
Here is what I've come up so far (Java 8 pseudocode):
AtomicReference<String> patternRef
AtomicLong modificationCount
ReentrantLock busy;
Consumer<List<ResultType>> resultConsumer;
// This is called in a background thread every time the user presses a key
void search(String pattern) {
// Update the pattern
synchronized {
patternRef.set(pattern)
modificationCount.inc()
}
try {
if (!busy.tryLock()) {
// Another search is already running, let it handle the change
return;
}
// Get local copy of the pattern and modCount
synchronized {
String patternCopy = patternRef.get();
long modCount = modificationCount.get()
}
while (true) {
// Try the search. It will return false when modificationCount changes before the search is finished
boolean success = doSearch(patternCopy, modCount)
if (success) {
// Search completed before modCount was changed again
break
}
// Try again with new pattern+modCount
synchronized {
patternCopy = patternRef.get();
modCount = modificationCount.get()
}
}
} finally {
busy.unlock();
}
}
boolean doSearch(String pattern, long modCount)
... search database ...
if (modCount != modificationCount.get()) {
return false;
}
... prepare results ...
if (modCount != modificationCount.get()) {
return false;
}
resultConsumer.accept(result); // Consumer for the UI code to do something
return modCount == modificationCount.get();
}
Did I miss some important point? A race condition or something similar?
Is there something in Java 8 which would make the code above more simple?
The fundamental problem of this code can be summarized as “trying to achieve atomicity by multiple distinct atomic constructs”. The combination of multiple atomic constructs is not atomic and trying to reestablish atomicity leads to very complicated, usually broken, and inefficient code.
In your case, doSearch’s last check modCount == modificationCount.get() happens while still holding the lock. After that, another thread (or multiple other threads) could update the search string and mod count, followed by finding the lock occupied, hence, concluding that another search is running and will take care.
But that thread doesn’t care after that last modCount == modificationCount.get() check. The caller just does if (success) { break; }, followed by the finally { busy.unlock(); } and returns.
So the answer is, yes, you have potential race conditions.
So, instead of settling on two atomic variables, synchronized blocks, and a ReentrantLock, you should use one atomic construct, e.g. a single atomic variable:
final AtomicReference<String> patternRef = new AtomicReference<>();
Consumer<List<ResultType>> resultConsumer;
// This is called in a background thread every time the user presses a key
void search(String pattern) {
if(patternRef.getAndSet(pattern) != null) return;
// Try the search. doSearch will return false when not completed
while(!doSearch(pattern) || !patternRef.compareAndSet(pattern, null))
pattern = patternRef.get();
}
boolean doSearch(String pattern) {
//... search database ...
if(pattern != (Object)patternRef.get()) {
return false;
}
//... prepare results ...
if(pattern != (Object)patternRef.get()) {
return false;
}
resultConsumer.accept(result); // Consumer for the UI code to do something
return true;
}
Here, a value of null indicates that no search is running, so if a background thread sets this to a non-null value and finds the old value to be null (in an atomic operation), it knows it has to perform the actual search. After the search, it tries to set the reference to null again, using compareAndSet with the pattern used for the search. Thus, it can only succeed if it has not changed again. Otherwise, it will fetch the new value and repeat.
These two atomic updates are already sufficient to ensure that there is only a single search operation at a time while not missing an updated search pattern. The ability of doSearch to return early when it detects a change, is just a nice to have and not required by the caller’s loop.
Note that in this example, the check within doSearch has been reduced to a reference comparison (using a cast to Object to prevent compiler warnings), to demonstrate that it can be as cheap as the int comparison of your original approach. As long as no new string has been set, the reference will be the same.
But, in fact, you could also use a string comparison, i.e. if(!pattern.equals(patternRef.get())) { return false; } without a significant performance degradation. String comparison is not (necessarily) expensive in Java. The first thing, the implementation of String’s equals does, is a reference comparison. So if the string has not changed, it will return true immediately here. Otherwise, it will check the lengths then (unlike C strings, the length is known beforehand) and return false immediately on a mismatch. So in the typical scenario of the user typing another character or pressing backspace, the lengths will differ and the comparison bail out immediately.

Is there some syntactic sugar for matching on deeply nested Option and Result chains?

I am issuing calls that return an Option that contains a Result which contains another Option that contains custom variants.
I am only ever interested in a specific chain of variant results like this:
if let Some(Ok(Some(CustomVariant(Some(value))))) = expr {
// handle value case
}
This is getting quite verbose and not really helpful, since I actually treat it as a single Result in all of my code. Can I somehow alias this code so that instead of writing the entire chain of Options and Results I can do something similar to:
alias TheCase(value) = Some(Ok(Some(CustomVariant(Some(value))));
if let TheCase(value) = expr {
//handle value
}
You don't need such an alias, just use a function to retrieve the one case you want:
fn oneCaseICareAbout(value: &Option<Result<Option<Foo>, Bar>>) -> Option<&Foo> {
if let Some(Ok(Some(CustomVariant(Some(value)))) = value {
Some(value)
} else {
None
}
}
if let Some(value) = oneCaseICareAbout(expr) {
//handle value
}
I would however consider refactoring your code not to use such a type. Option<Result<_, _>> is already a red flag, but Some(Ok(Some(CustomVariant(Some(…)))) is just on the edge of insanity!

Which one is faster? Two fors inside of an if-else statement or a single for statement with an if-else statement?

I don't know if that forum is the right place for doing such a question but here it is:
Which one should I use for more optimization? A single for statement with an if-else statement or two for statement inside of an if-else?
For example, supposing that items is a huge list:
void doSomething(List items, boolean test)
{
for(item : items) {
if (test) {
// do A statements
} else {
// do B statements
}
}
}
And the second example:
void doSomething(List items, boolean test)
{
if (test) {
for (item : items) {
// do A statements
}
} else {
for (item : items) {
// do B statements
}
}
}
So, I know that the second example may look like a code duplication, but the point is, as we can see on the first example, the computer is going to make the same tests over and over for each item of the list, is it really a problem for optimization? Since inside the loop, the test boolean is not going to change its value at all.
I would prefer the second construct as it avoids the repetition of the test.
As claimed by others, the compiler might do the transformation. But you don't know for sure, and the cost of duplicating the loop statement isn't significant.

SonarQube - Nested If Depth

I'm getting this violation on sonarqube Nested If Depth
if (some condition){
some code;
if (some condition) {
some code;
}
}
and also here:
for (some condition) {
if (some condition) {
some code;
}
}
how can I reduce the depth?
Answer is already accepted, but doesn't answer the actual question.
So for completeness sake I want to add my 2 cents.
For reference see This question here
The example you list looks like it is dealing with guard conditions. Things like "only run this method if ...." or "only perform this loop iteration if ...."
In these cases, if you have 3 or 4 groups of guards you might end up indenting very deeply, making the code harder to read.
Anyways the way to fix this code to be more readable is to return early.
instead of
if (some condition) {
// some code
if (some other condition) {
// some more code
}
}
You can write
if (!some condition) {
return;
}
// some code
if (!some other condition) {
return;
}
// some more code
You now only every have 1 level of nesting and it is clear that you do not run this method unless 'some condition' has been met.
The same goes for the loop, using continue:
for (some condition) {
if (some other condition) {
// some code;
}
}
becomes
for (some condition) {
if (!some other condition) {
continue;
}
// some code
}
What you would state here is that unless 'some other condition' is met, you skip this loop.
The real question is why is the max depth set to 1 ? It's overkill.
This kind of rule is meant to keep your code readable. More than 2 nested blocks can make the code unreadable, but 1-2 will always be readable.
If you decide to keep the max depth set to 1, you need to refactor your code and put every 2nd condition check inside a separate method. No offense, but unless you have a very specific and good reason to do it, it looks like a bit stupid.

Where to put comments in an if-then-else construct? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I never decided on what the best way is to comment if-then-else constructs, so I never standardized on a consistent way to comment them.
I appreciate any insights.
Some options:
a)
if (blabla) {
// this comment explains what happens in the IF case
dothis();
} else {
// this comment explains what happens in the ELSE case
dosomethingelse();
}
drawback: in case of multiple dothis() statements, I like to comment the major blocks, and in that case it isn't always clear if the IF-comment belongs to the first dothis() block or to the whole IF case
or b)
if (blabla) { // this comment explains what happens in the IF case
dothis();
} else { // this comment explains what happens in the ELSE case
dosomethingelse();
}
drawback: only works for short comments. I usually comment IF-THEN-ELSE constructs if the IF and ELSE case isn't directly clear from the code, which typically requires a comment longer than one line.
or c)
// if the following happens
if (blabla) { // then do this
dothis();
} else { // or else do this
dosomethingelse();
}
PS: I know about "the code should be self explanatory", but this isn't always the case...
For me, a comment above the IF explains the IF statement itself. For example, if the condition being tested is particularly complex.
A comment in the block below the IF or ELSE describes what's going once the condition has been evaluated and a choice made.
So like this:
//Is this a favoured customer and do we have a promotion?
if customer.special() and monthly.hasOffer() {
//Add discount
invoice.addDiscount();
}
else {
//Add note about favoured customer scheme
invoice.addNotes(JOIN_OUR_DISCOUNT_SCHEME);
}
I never gave it very much thought; personally and when required I have put comments above the IF and ELSE statements. This gives me nice separation between the comments about the branch statements and comments about the code.
// comment about the if statement
if (expression)
{
// comment about the code
doSomething();
}
// comment about the else statement
else
{
// comment about the code
doSomethingElse();
}
I also note that I am the only answer so far to use the "open curly brace style", which might be a throw back to my Pascal days although I do prefer the visual justification of begin and ends of code blocks, so my comment style may not work for the "closed curly brace style community.
I'd do case a) but with an extra bit of whitespace:
if (blabla) {
// This explains the whole if case
// Can comment here for specific block comments
doThis();
} else {
// This explains the else case
// Same again
doSomethingElse();
}
Personally, I findi it better to write code that doesn't require little comments that say "about do do x", followed by "DoX()". If necessary, rather than write a comment saying "do x because of y", I'd prefer to write a method named "DoXBecauseOfY". If later refactoring removes the "BecauseOfY" part, then it still makes better sense to put a comment before the if statement, documenting the overall logic.
Of course, you then need to reduce the amount of code within each branch to the point where you can read the entire if statement at once.
Use what makes sense to you, I guess (unless you're working under a coding standard that specifies commenting style). Personally I don't use (c) because it's inconsistent between the first and following cases. I do occasionally use (b) when a short comment will do but generally I prefer (a). If I'm commenting several sub-blocks within the if block, I might leave a blank line after the case comment:
if (blabla) {
// here's a comment about this case
// comment about this bit of code
bit_of_code();
// comment about this other bit of code
other_bit_of_code();
}
and so on.
// Not very much sure, but here is a snippet of my code
// tweak URL as per query params and hash index positions
if (hasQueryParams && hashPos > -1) {
// both query params and hash available
...
...
} else if (hasQueryParams) {
// only query params available
...
...
} else if (hashPos > -1) {
// only hash available
...
...
} else {
// neither query params nor hash available
...
...
}
From the oracle java docs for code conventions
Single line comments for if-else:
if (condition) {
/* Here is a single line comment. */
...
}
Single line very short comments for if-else:
if (a == 2) {
return TRUE; /* special case */
} else {
return isprime(a); /* works only for odd a */
}
Multi line comments for if-else:
if (condition) {
/*
* Here is a block comment.
*/
}
just to add the missing answer for the else's comment placement, which in my opinion is the best placement for code readability for the following reasons:
if the comment is put above the else it breaks the if-else continuity
if put inside it can mixes with the comment of the first statement inside the else
// match jth arc
if (j < Count)
{
// arc matched
if (arcs[j].IsBlue) List.Add(arcs[j])
}
else // all arcs were matched
{
// check if there more arcs
if (arcs[j + 1] != null) continue;
}
It looks really good if you collapse the blocks
// match jth arc
if (j < Count)|...|
else // all arcs were matched|...|
How about this style?
Using // comment for whole if-else statement description,
and /* */ comment for inner description. I use /* */ comment for not being confused with inner-comment of if-else statement.
// Process1
if (cond1-1) {
/* Process1 > Process1-1 */
Process1-1();
// Process1-1 description...
Process1-1();
Process1-1();
...
} else if (cond1-2) {
/* Process1 > Process1-2 */
// Process1-2 description...
Process1-2();
Process1-2();
Process1-2();
...
// Process1-2
if (cond1-2-1) {
/* Process1 > Process1-2 > Process1-2-1 */
Process1-2-1();
Process1-2-1();
Process1-2-1();
...
} else if (cond1-2-2) {
/* Process1 > Process1-2 > Process1-2-2 */
Process1-2-2();
// Process1-2-2 description...
Process1-2-2();
// Process1-2-2 description...
Process1-2-2();
...
} else {
/* Process1 > Process1-2 > Process1-2-else */
Process1-2-else();
Process1-2-else();
Process1-2-else();
...
}
} else {
/* Process1 > Process1-else */
Process1-else();
Process1-else();
Process1-else();
...
}
How about this? Comment right after the if keyword. Readable like natural language, leaving possibly complex condition code only for those really interested.
if /* user is logged in */ (user && user.loggedin()) {
...
} else if /* user was logged in before */ (cookies.user && sizeof(cookies.user)>0 && cookies.user.value=="foobar" && some_other_things_in_a_long_condition) {
...
} else /* apparently there's no user */ {
...
}

Resources