Java If optimization - java

I do have the following statement:
isEnabled = false;
if(foo(arg) && isEnabled) {
....
}
public boolean foo(arg) {
some really long running code
}
Does it make sense to swap the statements inside the if?
if(isEnabled && foo(arg)) { ... }
Or does the compiler the optimization for me?

Note that the two expressions don't have the same behavior if foo() also has side effects.
If it is manipulating the state of the program, it makes a lot of difference if you always invoke it, or if you invoke it only as a dependency of the value of isEnabled.
For example, consider:
boolean foo(Object arg) {
someLocalVariable = arg;
//do some calculation and return an answer
}
It matters if you always invoke foo(), or if you invoke it only in the case where isEnabled is turned on, resulting in the following two expressions to be completely different from each other:
if (isEnabled && foo(arg)) { ...} //local variable changes only if isEnabled==true
if (foo(arg) && isEnabled) { ...} //local variable always changes

The compiler will not do any optimization in this case.
if(isEnabled && foo(arg)) { ... }
Is always the better approach.
Because i guess you know that when isEnabled is false it will not evaluate foo(arg). And compiler will maintain your sequence of instruction.

Does it make sense to swap the statements inside the if?
Yes. && will only evalute the sub-expressions until one is false. Then the complete exprission will be false, no matter what the other expressions evaluate to.

Since the compiler would have to keep the logic as it is (which includes the order of statements) it won't optimize that.
Suppose foo() has a side effect which some other part of the code relies on, changing the order might break that. Of course this isn't good style in most cases but the compiler can't rely on or enforce style so it has to trust the developer here.
Example:
int x = 0;
boolean foo(int arg) {
x = arg;
return x > 0;
}
void someMethod(int arg) {
boolean isEnabled = false;
if(foo(arg) && isEnabled) {
//whatever
}
//here you use x, I'll simply print it
System.out.println("x=" + x);
}
void someOtherMethod(int arg) {
boolean isEnabled = false;
if(isEnabled && foo(arg)) {
//whatever
}
//here you use x, I'll simply print it
System.out.println("x=" + x);
}
Now calling the methods:
someOtherMethod(7); //foo(7) will not be called so x will still be 0
someMethod(5);
you'll get the output
x=0
x=5

First of all, the Java compiler (which turns java source into bytecode) is pretty dumb. Out of the many optimization techniques known to compiler constructors, just a handful (like constant folding) are implemented by javac.
Whereas the Java just-in-time compiler does many many more things; but even the JIT will not change the order of arguments for you (as that can change the semantics of the underlying program).
Finally, when thinking about this code, performance should not be the motivation behind you changing it. Instead, you should worry about the semantics too. Do you want that foo() is executed (for side effects); or maybe do you not want that foo() runs all the time?
Of course, "foo()" could be doing many many things; and not executing it might gain some performance. But most likely: it will not matter (from a performance perspective).
In other words: stay away from micro-optimisations, see here for backing reasons to that recommendation.

Related

Mutation testing booleans with Java

I have very very little experience with Java and I'm facing some issues.
I've got a code that looks like the one below and a goal to kill all mutations of it.
public class MyClass {
protected transient boolean something = false;
public MyClass () {
something = true;
}
boolean isSomething () {
return something;
}
}
My test code looks like this
tester = MyClass();
assertTrue(tester.isSomething());
By running it with pitest, on Eclipse, it would generate the following mutations (all related to the return something statement):
Substituted 1 with 0
Removed assignment to member variable something
Substituted 1 with 0
Substituted 1 with -1
Substituted 1 with -1
Substituted 1 with 2
Substituted 1 with 0
Unfortunately, I just can't kill those 4 and 5 mutations, both that substitutes 1 with -1. Is there a way I could kill them?
There are a few issues here.
Firstly you look to have some experimental/research mutation operators enabled which are generating junk mutations. This will not happen if you stick with the default set.
As at the jvm level booleans are represented as integers of 0/1. Only the following mutations make sense
Substituted 1 with 0
Removed assignment to member variable something
(note that although the mutation makes sense in this case, the removal of member assignments is disabled by default as it can produce equivalent mutants)
You don't provide the full context so it is not clear if the repeated 1/0 substitutions are duplicates or distinct.
To kill these mutants there are two approaches. Firstly remove redundant code.
public class MyClass {
protected transient boolean something = true;
boolean isSomething () {
return something;
}
}
This is functionaly equivalent to the original code, but there is less of it.
Secondly you need tests.
Since you have made something protected I assume that MyClass has subclasses? If it does not then then code could be further reduced down to
public class MyClass {
boolean isSomething () {
return true;
}
}
And there is only one test you can write.
assertThat(new MyClass().isSomething()).isTrue();
If there are subclasses then you need tests that check that setup something to be true, and then assert that isSomething returns true, and another that sets it up to be false and asserts the method returns false.

Why can't we declare variables in if statement?

I know that there is a question like this on Stack Overflow but I want to know why we can't declare variables inside if statements so that we can save space by just utilizing the if scope.
For example, if I write:
if (int i) {
...
}
then I could use i only within the if scope, but if I write it outside of the if statement, then i variable should be in memory for the whole block.
if ( int i ) => int i is not a boolean expression, so this won't work.
if ( booleanExpr ){
int a = 5;
...
}
here a is a local variable within the if block. At the end of the if-block, it is removed from the stack and becomes unusable.
int a = 5;
if ( booleanExpr){
...
}
Here a is not local to the if block, but to the containing method. So, it will be on the stack during the entire execution of the method (starting from its declaration).
a could also be an instance or static variable to the class, then it's accessible in every method of the class (instance variables are not accessible in a static context, though)
why can't we declare variables in the if statement?
Because the Java Language Specification does not allow it.
if I write if(int i){} then I could use i only for if the scope
You can use blocks
public void someMethod() {
{
int i = 1; // visible only to the current block
} {
int i = 0; // visible only to the current block
if (i == 0) {
System.out.println("i = " + i);
}
}
// compiler error, because i is not visible outside the block
System.out.println(i);
}
But this decreases the readability of your code. So I would recommend to NOT use it.
An if statement is a test, so declaring a variable in an if does not make any sense.
Think about it, an if is for something like this:
if(a == 1){
// blan
}
If you declare a in the if condition, you are essentially comparing 2 static values.
Lots of languages let you declare an "iterator" vairable in a for loop:
if(int a = 0 ; a < somelist.length ; a++){
// Do something
}
// a is out of scope here
You can restrict the scope of your variable to make it visible only in the if statement like this:
System.out.println("Hello World!");
//use a codeblock to restrict access
{
int i = 4;
if(i!=0)
{
System.out.println("i = "+i);// this is OK
}
}
System.out.println("i = "+i);//this is not OK
why can't language support it
That's the wrong question to ask. The real question is:
Is there a compelling reason for the language to support it?
That is, is there a compelling reason to implement it, exhaustively test it for all possible edge cases, and maintain it in all future versions of the language?
In this case, no. There isn't. It might be handy in a small number of cases, but it's not a core feature of the language and isn't really necessary. So there's no compelling reason to make the implementation of the language more complex and incur significant cost now and well into the future to support it.
if is a conditional and there is no valid use-case when you declare a variable inside the conditional.
If your conditional is more complex, you can implement a few methods for it and inside those methods you can use those variables, however, if you need that variable outside the if, then define it outside the if in the correct scope.

Why isn't "int someVal=0" for an instance field considered dead code?

Why do I get no dead code warning for the initialisation of someVal here?
public class DeadCode {
private int someVal = 0;
public DeadCode(int someVal) {
this.someVal = someVal;
}
public int getSomeVal() {
return someVal;
}
public void setSomeVal(int someVal) {
this.someVal = someVal;
}
}
The Java compiler is supposed to pick up on dead code and issue a warning; but this is dead twice over, and passes by without a hitch.
It's dead twice over because
Java automatically initialises instance fields to 0 or equivalent;
the value of someVal can't be read without being written to.
I realise that the compiler can elide the assignment if it wants to, but that's true (by definition) of all dead code.
If there is a distinction to be made between dead code and code that has no effect, then I would expect
The assignment to variable someVal has no effect.
which is what I would get if I wrote
someVal = someVal;
in my code. But I don't get that either.
In any case, Wikipedia sees dead code elimination as removal of code that has no effect on program results; and this is certainly a case of that.
I think the real answer is that many people would find a warning for that code to be pretty annoying.
As a technicality, though, the initializer does not constitute dead code because its effect can, in principle, be observed in an improperly synchronized multithreaded program.
Integer field is a simplistic use case. What if you had something like this, notice the parameterless constructor:
public class DeadCode {
private List<Integer> someVal = new ArrayList<>();
public DeadCode() {
}
public DeadCode(Iterable<Integer> someVal) {
this.someVal.addAll(someVal);
}
public Iterable<Integer> getSomeVal() {
return someVal;
}
public void addSomeVal(int someVal) {
this.someVal.add(someVal);
}
}
You have to create a list, yes you could do it in the constructor Now the compiler needs to be a lot more intelligent to be able to determine in which cases it wasteful to initialize field. I guess they opted for consistent and straightforward behavior.

Quick conditional without return value Java [duplicate]

I was wondering if it was possible to do a ternary operation but without returning anything.
If it's not possible in Java is it possible in other languages, if so which ones apply?
name.isChecked() ? name.setChecked(true):name.setChecked(false);
No, you can't. But what's the point of this over an if-else statement? Are you really trying to save 7 characters?
if (name.isChecked()) {
name.setChecked(true);
} else {
name.setChecked(false);
}
or if you prefer bad style:
if (name.isChecked()) name.setChecked(true); else name.setChecked(false);
Never mind the fact that you can just do (in this case):
name.setChecked(name.isChecked());
The point of the ternary or "conditional" operator is to introduce conditionals into an expression. In other words, this:
int max = a > b ? a : b;
is meant to be shorthand for this:
int max;
if ( a > b ) {
max = a;
} else {
max = b;
}
If there is no value being produced, the conditional operator is not a shortcut.
I was wondering if it was possible to do a ternary operation but without returning anything.
No it is not possible:
The 2nd and 3rd operands are required to be non-void expressions; i.e. they must produce some actual value.
"It is a compile-time error for either the second or the third operand expression to be an invocation of a void method." - JLS 15.25.
A ternary expression is an expression, and cannot be used as a statement.
"Certain kinds of expressions may be used as statements by following them with semicolons." ... and the ternary expression is not one of those kinds - JLS 14.8.
If you really, really want to use a ternary expression but not use the value of the expression, then the simplest thing is to assign the value to a dummy variable, and add an annotation to suppress the warning about the variable not being used.
But a better idea is to use a plain if statement.
If it's not possible in Java is it possible in other languages, if so which ones apply?
I'm a bit rusty, but I believe that C, C++ and Perl all allow arbitrary expressions to be used in places where their values are not used.
Sometimes, you can use ternary operation on method arguments to solve your request.
name.setChecked(name.isChecked() ? true : false);
By the way, the best solution for your problem is
name.setChecked(name.isChecked());
I assume the use case in the question is just a poor example because it's equivalent to the following statement:
name.setChecked(name.isChecked());
... which doesn't make sense either. But the intent is clear and there are indeed many relevant use cases.
The only viable and general solution is adding a helper method like this:
static void ternaryVoid(boolean condition, Runnable ifTrue, Runnable ifFalse) {
(condition ? ifTrue : ifFalse).run();
}
and using it like this:
ternaryVoid(name.isChecked(), () -> name.setChecked(true), () -> name.setChecked(false));
But it loses the elegance of ternary operator and worth the 'effort' only if used by multiple parts of the code and only if nanoseconds don't matter.
But what's the point of this over an if-else statement? Are you really trying to save 7 characters?
I'm surprised that such statements appear in a form of rhetorical questions. Yes, saving 4 lines and making the code more elegant is important, especially in the context of functional programming.
Moreover, it's at least arguable whether void methods return a complete Void. Essentially, they return a notification of a completed task. This is why logically, ternary expression makes sense equally regardless of whether it returns something or nothing:
condition ? doThis() : doThat();
Here is a real world example of a class which may process millions of incremental updates per second:
public class DataHandler {
private final TreeMap<Integer, Long> tree = new TreeMap<>();
public void onUpdate(int price, long amount) {
if (amount == 0) {
tree.remove(price);
} else {
tree.put(price, amount);
}
}
}
If allowed, the onUpdate() method would be a nice ternary expression like this:
public void onUpdate(int price, long amount) {
(amount == 0) ? tree.remove(price) : tree.put(price, amount); // compilation error
}
Fortunately, in some cases like this, both target methods return values, and these values are of the same type, which is Long in this case. This allows either to make the onUpdate method to return the previous amount at price (which is even useful)
public Long onUpdate(int price, long amount) {
return (amount == 0) ? tree.remove(price) : tree.put(price, amount);
}
... or alternatively (e.g. in case the method is determined by an interface), to use a dummy variable and suppress its uselessness warning:
public void onUpdate(int price, long amount) {
#SuppressWarnings("unused")
Long dummy = (amount == 0) ? tree.remove(price) : tree.put(price, amount);
}
Otherwise, these solutions are not applicable, and as answered by others, doesn't exist. For instance, one may try the following:
Consumer<Void> dummy = (x) -> {};
dummy.accept(/*...*/);
but interestingly, the second line compiles with neither anything nor nothing as an argument.
It seems the best general solution is the above helper method ternaryVoid().
You have to return some value and it will not work if you want it to act like a void method which performs some action without a returning a value.
Hope this helps...
In java following code isn't possible:
(your-condition) ? (true-statements) : (false-statements)
for sample you can't compile following snipet code :
(1==1) ? System.out.println("") : System.out.println("");
you achieve following compilation error:
The left-hand side of an assignment must be a variable

Is a switch statement the fastest way to implement operator interpretation in Java

Is a switch statement the fastest way to implement operator interpretation in Java
public boolean accept(final int op, int x, int val) {
switch (op) {
case OP_EQUAL:
return x == val;
case OP_BIGGER:
return x > val;
case OP_SMALLER:
return x < val;
default:
return true;
}
}
In this simple example, obviously yes. Now imagine you have 1000 operators. would it still be faster than a class hierarchy? Is there a threshold when a class hierarchy becomes more efficient in speed than a switch statement? (in memory obviously not)
abstract class Op {
abstract public boolean accept(int x, int val);
}
And then one class per operator.
EDIT:
Sorry, I should have been more specific by the look of the answers.
The Operator is totally unknown and I'm using JDk 1.4. No choice. No enums. No Closures. :(
The operator is chosen by the user among many many many choices. For simplicity sake, Imagine a GUI List with 1000 operations, when user selects one, op code of the switch statement is chosen. Using a class hierarchy, user would select a class.
I'm asking this question because someone must have tested it before. I don't feel like creating 1000 classes and 1000 bogus op codes to test it. If nobody has done it. I will test it and report the results, if they may have any meaning at all.
EDIT:
Okay, since you have to use JDK 1.4, my original answer is a no-go (left below for reference). I would guess that the switch is not as fast as the abstract class-based solution when you're just looking at the apply(which,a,b) vs which.apply(a,b) call. You'll just have to test that.
However, when testing, you may also want to consider start-up time, memory footprint, etc.
ORIGINAL:
public enum OPERATION {
// ...operators+implementation, e.g.:
GREATER_THAN { public boolean apply(int a, int b) { return a > b; } };
public abstract boolean apply(int a, int b);
}
usage:
OPERATION x = //..however you figure out which
boolean result = x.apply(a,b);
this is one of the case uses in Effective Java for enums. It works exactly like the switch, only less confusing.
Because of the way a switch statement is usually implemented in a jvm, with a lookup table, it is likely it is going to be faster, with a small or big number of operators. This is just guessing; to have a definite answer you need to benchmark it on the system it is intended to run.
But, that is just a micro-optimization which you shouldn't care about unless profiling shows that it could really make a difference. Using integers instead of a specific class (or enum) makes code less readable. A huge switch statement with 1000 cases is a sign of a bad design. And that will have an influence on the code that is using the operators; less readable, more bugs, harder to refactor,...
And to get back to performance, which seems to be the goal here. In hard to read, badly designed code, the changes required for macro-optimizations become harder. And those optimizations are usually a lot more important than micro-optimizations like this switch.
I do not know what is fastest, nor do I think there are any guarantees. Optimization of code is very much dependent on both compiler and runtime.
I do think that it's hard to beat a switch statement. Due to the limitations Java puts on the types which can be switched it can fairly easily be compiled to a lookup table, which is about the fastest access you can get.
Use a table-driven method, as a previous poster pointed out you may use the operator as the index of an array. The value stored in the array could be an instance of a class that performs the comparison. The array can be initialized statically, or better on-demand (lazy loading pattern).
e.g.
// Interface and classes
interface Operator {
boolean operate(int x, int y);
}
class EqualsOperator implements Operator {
boolean operate(int x, int y){
return x==y;
}
}
class NotEqualsOperator implements Operator {
boolean operate(int x, int y){
return x=!y;
}
}
...
// Static initialization
Operator[] operators = new Operator[n];
operator[0] = new EqualsOperator();
operator[1] = new NotEqualsOperator();
...
// Switch
public boolean accept(final int op, int x, int val) {
operator[op].operate(x,val);
}
If the calling method already has to decide which operator value to use and call accept(), then the fastest thing would be to do the comparisons inline in that same calling method.
Alternatively, use three methods (or strategies):
public boolean acceptGreater(int x, int val) {
return x > val;
}
public boolean acceptLess(int x, int val) {
return x < val;
}
public boolean acceptEquals(int x, int val) {
return x == val;
}
I wouldn't look at this purely from a raw performance point of view, but I'd evaluate this as a refactoring candidate, see c2:Refactor Mercilessly. I liked the answer given to code resuability:
If you repeat it once, copy it.
If you repeat it twice, refactor it.
I'd identify the adding of multiple case statements as repetition, and then I'd refactor to implement the Strategy Pattern.
I'd name the operator classes with a strategy suffix, and implement the execute method.
I've always found that the java switch statement is not as powerful as I need. In his last release lambdaj implements it with a smart use of closure and Hamcrest matcher.

Categories