Was ist der effizienteste Weg, gerade Zahlen in Java zu erkennen? [Duplikat]

7

Was wäre die effizienteste Methode, um festzustellen, dass eine Nummer sogar Java verwendet, und warum?

Würde es mit Modulo oder Subtraktion arbeiten, oder mit einer anderen Methode, an die ich eigentlich nicht gedacht habe?

Man stellt sich vor, ich könnte dies feststellen, indem ich eine einfache Testklasse mache - und ich kann - aber das würde wirklich nicht erklären, warum, oder?

Ich mache keine verrückte Performance-Einstellung für ein hohes Ziel, das viele Elemente schneller zu verarbeiten. Aber ich war neugierig, ob eine Methode sollte gegenüber der anderen als gängige Praxis bevorzugt werden. Genauso würden wir & anstelle von && nicht verwenden, warum % verwenden, wenn wir & verwenden können?

    
bharal 06.06.2013, 18:13
quelle

4 Antworten

17

Wenn Sie die Assembly überprüfen, die von Hotspot 7 dieser zwei Methoden generiert wird:

%Vor%

Sie werden sehen, dass, obwohl der Mod optimiert ist und im Grunde eine bitweise and tut, aber es hat ein paar zusätzliche Anweisungen, weil die beiden Operationen nicht genau gleichwertig sind *. Andere JVMs könnten es anders optimieren. Die Assembly wird unten als Referenz veröffentlicht.

Ich führte auch einen Mikro-Benchmark durch, der unsere Beobachtung bestätigt: isEventBit ist geringfügig schneller (aber beide laufen in ungefähr 2 nanoseconds und werden wahrscheinlich nicht viel von einem typischen Programm als Ganzes beeinflussen ):

%Vor%

isEvenBit

%Vor%

isEvenMod

%Vor%

* wie in den Kommentaren erwähnt, ist % nicht wirklich modulo; es ist der Rest. Also (i % 2) != (i & 1) wenn i < 0 . Die zusätzlichen Anweisungen im isEvenMod -Code setzen das Vorzeichen des Ergebnisses auf das Vorzeichen von i (und vergleichen es dann einfach mit Null, so dass der Aufwand verschwendet wird).

    
assylias 06.06.2013, 18:38
quelle
4
%Vor%     
K Boden 06.06.2013 18:20
quelle
4

TL; DR Die bitweise Version scheint am schnellsten zu sein. Benchmark und Beispielergebnisse unten.

Dies sollte schneller als modulo sein, da es nur zwei Schritte sind, die direkt in der Hardware behandelt werden können:

%Vor%

Hier ist ein Mikrobenzeichen, das meinen und aasylias 'Punkt beweist:

%Vor%

Bitweise ist immer etwas schneller (auch wenn Sie den Codeblock mit dem Modulo-Block umschalten). Beispielausgabe:

%Vor%     
jlordo 06.06.2013 18:16
quelle
4

Ein anderer Ansatz besteht darin, einen Mikro-Benchmark zu erstellen und den Zeitaufwand für jede Variante zu analysieren. Hier sind die Ergebnisse:

%Vor%

(Die Basislinie ist eine Methode, die nur i == 0 zurückgibt)

Fazit:

  • i & 1 ----- & gt; dauert etwa 1,75 ns
  • i << 31 - & gt; dauert etwa 2,00ns
  • i % 2 ----- & gt; dauert etwa 4,50ns

Mit anderen Worten, i % 2 ist 2x langsamer als i & 1 .

Anmerkungen: Benchmark mit jmh gemacht. Die Grundlinie ist hoch, weil ich Zufallszahlen erzeuge, um sicherzustellen, dass die Methode nicht weg optimiert wird. Tests laufen auf einem i7 @ 2.8GHz (d. H. Einem Zyklus = 0.35ns) mit Hotspot 7.

    
assylias 06.06.2013 21:19
quelle

Tags und Links