-1

I working on a hexgrid program and need to test if an angle is

  1. less than 30 degrees
  2. equal to 30 degrees
  3. between 30 and 60 degrees
  4. equal to 60 degrees
  5. greater than 60 degrees

I have

public int TestA(double angle)
{
    if(angle<=30)
        {
            if(angle==30)
                return ANGLE_EQUALS_30;
            else
                return ANGLE_LESS_THAN_30;
        }

    if(angle>=60)
        {
            if(angle==60)
                return ANGLE_EQUALS_60;
            else
                return ANGLE_GREATER_THAN_60;
        }
    return ANGLE_BETWEEN_30_AND_60;
}

but of course I could have

public int TestB(double angle)
{
    if(angle<30) return ANGLE_LESS_THAN_30;
    if(angle==30) return ANGLE_EQUALS_30;
    if(angle<60) return ANGLE_BETWEEN_30_AND_60;
    if(angle==60) return ANGLE_EQUALS_60;
    return ANGLE_GREATER_THAN_60;
}

Is TESTA really quicker than TESTB? Or does the compiler end up spliting an <= test into 2 tests (< and ==), so TESTA is actually performing more tests then TESTB?

I would just write a program to test it, but I have a feeling that it's going to be so close that programs running in the background will make more of a difference.

Roy
  • 974
  • 6
  • 11
  • 7
    Your last paragraph is very sensible. If you had started with that realization, you wouldn't have needed the rest of the question . . . – ruakh Mar 11 '14 at 05:37
  • haha,,agree with @ruakh..You are not writing any complex algorithm. So it doesn't make any difference whichever method you use.. – Stunner Mar 11 '14 at 05:44
  • The cost of a missed branch prediction is up to 100x more expensive. – Peter Lawrey Mar 11 '14 at 05:46

4 Answers4

4

The difference is completely negligible in the grand scheme of things.

Look at this demonstration. This isn't a java example, (javascript rather) but you can see why worrying about such micro optimizations won't really help solve real problems.

Worry about making your java source easy to read and maintain. The compiler deserves more credit than you think.

yamafontes
  • 5,552
  • 1
  • 18
  • 18
  • "Worry about making your java source easy to read and maintain. The compiler deserves more credit than you think." Well said. +1 for that – fareed Mar 11 '14 at 05:49
1

Please don't do premature optimization.

Real slowdowns occur because of bad algorithms, not bad implementations. Microptimizations like these should not be done up-front. Write maintainable code, run your software and only do optimizations when you run into real performance problems. If you run into performance problems, do profiling and check where exactly the problem is.

To your actual question regarding "<=" or "==". You won't know anyway what your compiler/virtual machine does with that code of yours. The compiler is probably much better anyway at figuring out, what the better choice is and will change your code accordingly.

For a definitive answer, I'd guess that "<=" is faster, because for processors that's just a single operation actually, and splitting it up might be two operations in the end.

noone
  • 19,520
  • 5
  • 61
  • 76
  • Thanks. And thanks to all the other answers as well. – Roy Mar 11 '14 at 05:56
  • I downvoted because 1) http://meta.stackexchange.com/questions/44485/how-should-we-handle-premature-optimization-discussion-in-optimization-questions 2) you "actual" answer is wrong because there is anyway the same number of comparisons in `testA` and `testB` given by OP. – leventov Mar 11 '14 at 11:22
  • No, I was wrong, your "actual" answer makes sense. But anyway I always downvote "premature optimization" answers in optimization questions – leventov Mar 11 '14 at 11:36
  • @leventov What's wrong the advice to not do premature optimizations? Most of the time it's just wasted time thinking about it, because a) the compiler optimizes it anyway (probably) b) in case it's not automatically optimized, it won't make any recognizable difference in 99% of the cases (like this one for example). With optimizations you probably make the code less readable and maintainable and if it's REALLY needed, then you can still do it in the end after profiling. – noone Mar 11 '14 at 17:17
  • @noone I can't add anything to http://meta.stackexchange.com/a/44488/235930. Assume that everybody ALREADY KNOWS that premature optimization is the root of all evil. Answer the question, please. – leventov Mar 11 '14 at 17:52
  • I disagree with that post on meta and it's obviously NOT the case that everyone knows about premature optimization, or WHEN to optimize. There are definitely interesting questions and relevant ones about optimization, but as long as someone doesn'T write "I profiled it, and found it's slow... but why and how to do I improve it?" I'll keep writing about it every time and try to educate the people who don't have a good understanding of the matter yet. I'll happily take all downvotes on my account then... – noone Mar 11 '14 at 18:15
1

Firstly, are you aware that double comparison is dangerous? See How dangerous is it to compare floating point values? and What is the most effective way for float and double comparison?

If angle argument is pretty random, I would use table lookup to avoid branch mispredictions:

private static final byte L30 = 0, E30 = 1, L60 = 2, E60 = 3, G60 = 4;

private static final byte[] ANGLE_TABLE = new byte {
    L30, L30, L30, L30, L30, L30, L30, L30, L30, L30, L30, L30, L30, L30, L30,
    L30, L30, L30, L30, L30, L30, L30, L30, L30, L30, L30, L30, L30, L30, L30,
    E30, L60, L60, L60, L60, L60, L60, L60, L60, L60, L60, L60, L60, L60, L60,
    L60, L60, L60, L60, L60, L60, L60, L60, L60, L60, L60, L60, L60, L60, L60,
    E60, G60, G60, ... depends on the angle upper limit
};

public static int test(double angle) {
    // but not Math.round() or floor(), they are very slow
    int intAngle = (int) (angle + 0.5);
    return ANGLE_TABLE[intAngle];
}
Community
  • 1
  • 1
leventov
  • 14,760
  • 11
  • 69
  • 98
  • Thanks. Comparing doubles had made me bang my head into the desk a few times :) In my actual program, this part is all integer math, but I simplified it greatly to ask my question. I should have used (int angle) in my examples here. – Roy Mar 11 '14 at 14:25
  • Surprised to hear Math.round() and floor() are very slow. I'll keep that in mind. – Roy Mar 11 '14 at 14:26
0

Try to use "else if" so that if the condition is met other checks are avoided.

public int TestB(double angle) {
    if(angle<30) return ANGLE_LESS_THAN_30;
    else if(angle==30) return ANGLE_EQUALS_30;
    else if(angle<60) return ANGLE_BETWEEN_30_AND_60;
    else if(angle==60) return ANGLE_EQUALS_60;
    return ANGLE_GREATER_THAN_60;
}
Aditya
  • 1,334
  • 1
  • 12
  • 23
ray
  • 457
  • 3
  • 9