Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacing If Statements?

I am trying to make my code more efficient and replace a bunch of if statements that I wrote. My program so far basically checks what operator (such as +, -, etc) is entered and then computes it. For example 1 + 5 gives 6. When the program evaluates the symbol between the number (the "+" in my example) it will check what the operator is and then proceed accordingly. For example if it's a "+", it will take the 1 and add 5. The code works like this:

switch (op) {
    case "+": // Addition
        return args[0] + args[1]; 
    case "-": // Subtraction
        return args[0] - args[1]; 
    case "*": // Multiplication
        return args[0] * args[1]; 
    case "/": // Division
        return args[0] / args[1]; 

I am wondering if it is possible to replace this whole block with some kind of statement that will detect the operator from the String and convert it into an operation? I realize for a few operators it is probably easier to use the switch statements but I have a lot of them and there is a 5-10ms difference between evaluating the operator at the top of the switch statements and at the bottom.

like image 736
Thomas Paine Avatar asked Feb 11 '15 17:02

Thomas Paine


People also ask

What is better than if-else?

A switch statement is significantly faster than an if-else ladder if there are many nested if-else's involved. This is due to the creation of a jump table for switch during compilation. As a result, instead of checking which case is satisfied throughout execution, it just decides which case must be completed.


2 Answers

In Java 8, you could use a map of lambda functions:

Map<String, IntBinaryOperator> operators = new HashMap<>();

operators.put("+", (a, b) -> a + b);
operators.put("-", (a, b) -> a - b);
operators.put("*", (a, b) -> a * b);
operators.put("/", (a, b) -> a / b);

...

return operators.get(op).apply(args[0], args[1]);

There's more indirection here, but it will give you O(1) amortized lookup time.

like image 124
John Kugelman Avatar answered Oct 06 '22 15:10

John Kugelman


The answer is the Strategy Pattern - you already have the nice Java 8 example, so here is the pre-lambda version (which also shows why lambdas were sorely needed):

public class CodeTest {

    private static interface ArithmeticStrategy {
        public double apply(double arg1, double arg2);
    }

    private static class AddArithmeticStrategy implements ArithmeticStrategy {
        @Override
        public double apply(double arg1, double arg2) {
            return arg1 + arg2;
        }
    }

    // ... other operations

    private static Map<String, ArithmeticStrategy> OPS = new HashMap<>();
    static {
        OPS.put("+", new AddArithmeticStrategy());
    }

    public static void main(String[] args) {
        // Add two numbers and print the result
        System.out.println(
                OPS.get("+").apply(22.3, 35.4));
    }
}
like image 32
BarrySW19 Avatar answered Oct 06 '22 16:10

BarrySW19