coptimizationbooleanatmega

What is the fastest algorithm for permutations of three conditions?


What is quickest method for evaluating three conditions in minimum steps?

I have three conditions and if any of the two comes out to be true,then whole expression becomes true else false.

I have tried two methods:

if ((condition1 && condition2) ||
    (condition1 && condition3) ||
    (condition2 && condition3))

Another way is to by introducing variable i and

i = 0;
if (condition1) i++;
if (condition2) i++;
if (condition3) i++;
if (i >= 2)
    // Do something

I want any other effective method better than the above two.

I am working in a memory-constrained environment (ATmega8 with 8 KB of flash memory) and need a solution that works in C.


Solution

  • It is always hard to give a just "better" solution (better in what regard—lines of code, readability, execution speed, number of bytes of machine code instructions, ...?), but since you are asking about execution speed in this case, we can focus on that.

    You can introduce that variable you suggest, and use it to reduce the conditions to a simple less-than condition once the answer is known. Less-than conditions trivially translate to two machine code instructions on most architectures (for example, CMP (compare) followed by JL (jump if less than) or JNL (jump if not less than) on Intel IA-32). With a little luck, the compiler will notice (or you can do it yourself, but I prefer the clarity that comes with having the same pattern everywhere) that trues < 2 will always be true in the first two if() statements, and optimize it out.

    int trues = 0;
    if (trues < 2 && condition1) trues++;
    if (trues < 2 && condition2) trues++;
    if (trues < 2 && condition3) trues++;
    // ...
    if (trues >= 2)
    {
        // do something
    }
    

    This, once an answer is known, reduces the possibly complex evaluation of conditionN to a simple less-than comparison, because of the Boolean short-circuiting behavior of most languages.

    Another possible variant, if your language allows you to cast a Boolean condition to an integer, is to take advantage of that to reduce the number of source code lines. You will still be evaluating each condition, however.

    if( (int)(condition1)
      + (int)(condition2)
      + (int)(condition3)
      >= 2)
    {
        // Do something
    }
    

    This works based on the assumption that casting a Boolean FALSE value to an integer results in 0, and casting TRUE results in 1. You can also use the conditional operator for the same effect, although be aware that it may introduce additional branching.

    if( ((condition1) ? 1 : 0)
      + ((condition2) ? 1 : 0)
      + ((condition3) ? 1 : 0)
      >= 2)
    {
        // Do something
    }
    

    Depending on how smart the compiler's optimizer is, it may be able to determine that once any two conditions have evaluated to true the entire condition will always evaluate to true, and optimize based on that.

    And the above caveats said, I have been working on code recently making changes that at first glance would almost certainly be considered premature detail optimization. If you have a requirement for high performance and use the profiler to determine which parts of the code are the bottlenecks, then the optimizations aren't premature. (They may still be ill-advised, however, depending on the exact circumstances.)