TL;DR The bitwise and version seems to be the fastest. Benchmark and sample results below.
This should be faster than modulo, since it's only two steps that can be handled directly in hardware:
if ((n & 1) == 0) {
// even number here
}
Here's a microbenchmark that proves my and aasylias' point:
// setup
int runs = 10;
int numbers = 200000000; // 200.000.000
int[] randomNumbers = new int[numbers];
Random random = new Random();
for (int i = 0; i < randomNumbers.length; i++) {
randomNumbers[i] = random.nextInt();
}
int even = 0;
int odd = 0;
// bitwiseAnd
long andStart = System.currentTimeMillis();
for (int i = 0; i < runs; i++) {
for (int number : randomNumbers) {
if ((number & 1) == 0)
even++;
else
odd++;
}
}
long andDone = System.currentTimeMillis();
long andDuration = andDone - andStart;
System.out.println("Even " + even + ", odd " + odd);
// reset variables
even = 0;
odd = 0;
// Modulo
long moduloStart = System.currentTimeMillis();
for (int i = 0; i < runs; i++) {
for (int number : randomNumbers) {
if (number % 2 == 0)
even++;
else
odd++;
}
}
long moduloDone = System.currentTimeMillis();
long moduloDuration = moduloDone - moduloStart;
// Done with modulo
System.out.println("Even " + even + ", odd " + odd);
// reset variables
even = 0;
odd = 0;
// Shift
long shiftStart = System.currentTimeMillis();
for (int i = 0; i < runs; i++) {
for (int number : randomNumbers) {
if ((number << 31) == 0)
even++;
else
odd++;
}
}
long shiftDone = System.currentTimeMillis();
long shiftDuration = shiftDone - shiftStart;
// Done with shift
System.out.println("Even " + even + ", odd " + odd);
System.out.println("Modulo Time " + moduloDuration);
System.out.println("Bitwise & Time " + andDuration);
System.out.println("Shift Time " + shiftDuration);
bitwise is always a bit faster (even if you switch the block of code with the modulo block). Sample output:
Even 999999530, odd 1000000470
Even 999999530, odd 1000000470
Even 999999530, odd 1000000470
Modulo Time 17731
Bitwise & Time 9672
Shift Time 10638