Ich wollte doch auch einmal testen um wieviel schneller die bitweise Modulo-Operation gegenüber dem 32-Bit-Modulo-Operator wirklich ist. Nachfolgend meine Testergebnisse für jeweils eine Milliarde Modulo-Operationen auf einem 32-Bit-System:
7637 ms Zeit benötigt für Modulo-Berechnungen mittels 32-Bit-%-Operator.
350282 ms Zeit benötigt für Modulo-Berechnungen mittels 64-Bit-Modulo-Funktion IEEEremainder().
1624 ms Zeit benötigt für bitweise Modulo-Berechnungen.
Die bitweise Modulo-Operation ist demnach auf meinem Testrechner um das drei- bis vierfache schneller gegenüber dem 32-Bit-Modulo-Operator % und nochmal viel schneller gegenüber der 64-Bit-Modulo-Funktion IEEEremainder(). Der prozentuale Geschwindigkeitsgewinn ist beachtlich, aber heutige Prozessoren sind so schnell das es keine große Rolle mehr spielt - eine Ausnahme bilden mit Millionen Modulo-Operationen die (rollenden) Hash-Funktionen.
Außerdem ist gerade bei 64-Bit-Datentypen die bitweise Modulo-Operation zu bevorzugen, allerdings funktioniert sie nur mit Zweierpotenzen als Divisor.
Bei dem Modulo-Operator % sollte man immer überprüfen wie die native Implementierung negative Zahlen verarbeitet, denn das ist je nach System unterschiedlich.
Ergänzung: Zumindest im .NET-Framework liefert die IEEEremainder-Funktion zwar das gleiche Ergebnis wie der Standard-Modulo-Operator, aber die Formeln nach der sie den Rest bilden sind unterschiedlich.
In Java erfordert der %-Operator jedenfalls eine 32-Bit-Integerzahl, auf 64-Bit-long-Werte kann man ihn ohne bereichseinschränkenden int-Cast nicht anwenden.
import java.io.File;
import java.lang.Math;
public class Modulo {
public static void main(String[] args)
{
/* Variante 1 mit 32-Bit-Modulo-Operator */
long completeTimeBefore = System.currentTimeMillis();
int temp = 0;
for (int i=1;i<=1000000000;i++)
{
temp = i % 1024;
}
System.out.println("letzte Berechnung: " + temp);
long completeTimeAfter = System.currentTimeMillis();
long completeTimeDiff = completeTimeAfter - completeTimeBefore;
System.out.println(completeTimeDiff + " ms Zeit benötigt für Modolu-Berechnungen mittels 32-Bit-%-Operator.\n");
/* Variante 2 mit 64-Bit-Modulo-Operator */
completeTimeBefore = System.currentTimeMillis();
double temp2 = 0;
for (int i=1;i<=1000000000;i++)
{
temp2 = java.lang.Math.IEEEremainder(i, 1024);
}
System.out.println("letzte Berechnung: " + temp2);
completeTimeAfter = System.currentTimeMillis();
completeTimeDiff = completeTimeAfter - completeTimeBefore;
System.out.println(completeTimeDiff + " ms Zeit benötigt für Modolu-Berechnungen mittels 64-Bit-Modulo-Funktion IEEEremainder().\n");
/* Variante 3 mit bitweiser Modulo-Berechnung */
completeTimeBefore = System.currentTimeMillis();
for (int i=1;i<=1000000000;i++)
{
temp2 = i & 1023;
}
System.out.println("letzte Berechnung: " + temp2);
completeTimeAfter = System.currentTimeMillis();
completeTimeDiff = completeTimeAfter - completeTimeBefore;
System.out.println(completeTimeDiff + " ms Zeit benötigt für bitweise Modulo-Berechnungen.\n");
}
}