<div dir="ltr"><div class="gmail_default" style="font-family:arial,sans-serif">I hope this is the appropriate list for this question.</div><div class="gmail_default" style="font-family:arial,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,sans-serif">Given the following Java code to test if a number is even or odd I observed unexpected results.</div><div class="gmail_default" style="font-family:arial,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,sans-serif">boolean evenA = ((i % 2) == 0);</div><div class="gmail_default" style="font-family:arial,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,sans-serif">boolean evenB = ((i & 1) == 0);</div><div class="gmail_default" style="font-family:arial,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,sans-serif">I expect the bitwise AND to be the fastest, as modulo operations are generally slower. The masking operation should never take more CPU cycles than the modulo operation.<br></div><div class="gmail_default" style="font-family:arial,sans-serif">This in fact is true, but only until the code is JIT compiled, and then the performance flips and the modulo version is notably faster.</div><div class="gmail_default" style="font-family:arial,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,sans-serif">This remains the case for checking if 'i' is evenly divisible by 4, using (i % 4) vs (i & 3).  Only when I get to checking for divisibility by 8 using (i % 8) vs (i & 7) do I see the performance shift to masking's favour after JIT compiling.</div><div class="gmail_default" style="font-family:arial,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,sans-serif">I suspect there is an optimization somewhere in the JIT compiler that sees the modulo 2 pattern and outputs optimized code that is not in fact doing a modulo calculation.  What I don't understand is how it ends up faster than the bit-mask version.  The JIT compiler appears to be undoing my attempted optimization.</div><div class="gmail_default" style="font-family:arial,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,sans-serif">Am I making a mistake here (other than assuming what is faster before profiling)?</div><div class="gmail_default" style="font-family:arial,sans-serif">Is this something that could be improved/fixed in the compiler?</div><div class="gmail_default" style="font-family:arial,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,sans-serif">Regards,</div><div class="gmail_default" style="font-family:arial,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,sans-serif">Scott</div><div class="gmail_default" style="font-family:arial,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,sans-serif">My simple experiment:</div><div class="gmail_default" style="font-family:arial,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,sans-serif">  public static void main(String [] args) {<br>    for (int i = 0; i < 10; i++) {<br>      long start = System.nanoTime();<br>      long maskCount = mask();<br>      var maskTime = Duration.ofNanos(System.nanoTime()-start);<br>      System.out.printf("%d     mask method took: %s%n", maskCount, maskTime);<br>      start = System.nanoTime();<br>      long moduloCount = modulo();<br>      var moduloTime = Duration.ofNanos(System.nanoTime()-start);<br>      System.out.printf("%d  modulo method took: %s%n", moduloCount, moduloTime);<br>      System.out.println("fastest: " + ((maskTime.compareTo(moduloTime) < 0) ? "MASK" : "MODULO"));<br>    }<br>  }<br>  static long modulo () {<br>    long count = 0;<br>    for (int i = 0; i < 2_000_000_000; i++) {<br>      if ((i % 2) == 0)<br>        count++;<br>    }<br>    return count;<br>  }<br>  static long mask() {<br>    long count = 0;<br>    for (int i = 0; i < 2_000_000_000; i++) {<br>      if ((i & 1) == 0)<br>        count++;<br>    }<br>    return count;<br>  }<br></div></div>