Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Hallo zusammen, ich muss in einer Bytevariablen die Position des ersten positiven Bits von Links beginnend bei 0 ermitteln. Ich habe zwei mögliche Varianten programmiert, frage mich allerdings welche denn nun schneller ist:
Ich würde mal vermuten, dass der Logarithmus nicht so schnell ist.
Der Code aus "highestOneBit" dürfte noch etwas schneller sein als deine Variante (der hat weniger Befehle und keine Sprünge).
Code:
byte x = ...
int pos = Integer.highestOneBit( x );
Allerdings frag ich mich, wieso du das wissen willst. Optimierungen auf dieser Ebene bringen so gut wie garnichts...
mit einfachen Tests kann man da aber auch was rausfinden:
Code:
class Test {
public static void main(String[] args) throws Exception {
long time = 0;
time = System.currentTimeMillis();
for (int j = 0; j < 10000; j++) {
for (int i = -120; i < 120; i++) {
byte b = (byte) i;
pos2(b);
}
}
System.out.println("time: " + (System.currentTimeMillis() - time));
time = System.currentTimeMillis();
for (int j = 0; j < 10000; j++) {
for (int i = -120; i < 120; i++) {
byte b = (byte) i;
pos1(b);
}
}
System.out.println("time: " + (System.currentTimeMillis() - time));
}
private static int pos1(byte prm) {
return (int) (Math.floor(Math.log(prm) / Math.log(2)));
}
private static int pos2(byte prm) {
for (byte i = 0; i < 8; ++i) {
if ((prm & (0x80 >> i)) != 0x00) {
return 7 - i;
}
}
return -1;
}
}
wären die Zahlen eng, müsste man evtl. noch die Schleifenlogik usw. mal leer zählen,
außerdem mal die Reihenfolge vertauschen und ähnliche Gegentests,
aber hier ist das Ergebnis recht deutlich
150ms Bitrechnung
>3000ms Math
die Math-Variante liefert außerden bei negativen bytes 0, die andere 7,
Integer.highestOneBit() kann ich mangels Java 1.5 grad nicht testen aber kann ja schnell eingefügt werden
Juhuu, meine Methode scheint sogar schneller als die der Standardbibliothek zu sein.
@Beni: Wie Du siehst, kann sich so etwas lohnen.
Und wie man sieht, sind die Methoden der Standardbibliothek relativ langsam. Ich meine, die von Sun werden ja wohl nicht jeden Idioten da programmieren lassen, oder? ???:L
Sieht aus, als täten sie's doch. :lol:
Ark
EDIT2: Hm, na gut, meine Methode ist ja private, die mitgelieferte jedoch public … wird vllt. doch etwas schwieriger einzuschätzen.
Ich würde es zu gerne machen, nur checke ich nicht ganz den Code. @_@
Hier aus dem Quelltext java.lang.Integer:
Code:
public static int highestOneBit(int i) {
// HD, Figure 3-1
i |= (i >> 1);
i |= (i >> 2);
i |= (i >> 4);
i |= (i >> 8);
i |= (i >> 16);
return i - (i >>> 1);
}
Schreibe das mal bitte jemand für byte i um? Ich kann gerade nicht, keine Zeit.
MfG
Ark
EDIT: Ach so, jetzt verstehe ich das!
EDIT2: Dann müsste das für byte wohl so aussehen:
Code:
public static int pos4(byte i) {
i |= (i >> (byte)1);
i |= (i >> (byte)2);
i |= (i >> (byte)4);
return i - (i >>> (byte)1);
Das scheint bisher also am schnellsten. (@Beni: :applaus: ) Aber kommt dabei auch tatsächlich das raus, was wir wissen wollten? ???:L
Ark
EDIT3: Quark!
Integer.highestOneBit(int) errechnet eine Zahl, die als einziges das höchste der in der eingehenden Zahl vorkommenden gesetzten Bits gesetzt hat, jedoch nicht die Stelle dieses Bits! Nur das höchste gesetzte Bit bleibt gesetzt erhalten, alle anderen Bits werden gelöscht.
Darum ist dieser Algorithmus nicht mit den anderen hier genannten vergleichbar; sie lösen völlig verschiedene Probleme.
--> Mein Algorithmus ist der beste.
Ark
EDIT4: Hier mal eine Skizze, wie das in Assembler aussehen könnte:
benötigt: Zählerregister, Akku
Eingabe: Akku mit zu untersuchender Zahl
Zählerregister mit 7 laden
Akku OR Akku
wenn Zero-Flag, dann zu .trivial
wenn Negative-Flag, dann zu .ende
.schleife:
Akku SHL 1
Zählerregister dekrementieren
wenn nicht Negative-Flag, dann zu .schleife
.ende:
Rücksprung
.trivial:
Zählerregister mit -1 (Zweierkomplement) laden
Rücksprung
Ausgabe: Zählerregister mit Position
verändert: Akku