2013-10-04 3 views
0

При работе с поплавками IEEE754 я нашел два способа обнуления верхних 9 бит 32-битной переменной. Кто-нибудь из них лучше другого?Бит-маскировка против смещения (+ java bytecode)

связанное с Java добавление: есть ли какой-либо список, содержащий информацию об эффективности работы? Я случайно обнаружил, что BIPUSH, как правило, должен быть быстрее, чем LDC, но не намного больше.

// 10111111110010100011110101110001 bits 
// 00000000010010100011110101110001 significand 

int bits = 0b10111111110010100011110101110001; 
int significand = bits & 0b11111111111111111111111; 
int significand2 = bits <<9>>> 9; 

Bytecode ...

L4 
    LINENUMBER 49 L4 
    ILOAD 0 
    LDC 8388607 // = 0b11111111111111111111111 
    IAND 
    ISTORE 5 
L5 
    LINENUMBER 50 L5 
    ILOAD 0 
    BIPUSH 9 
    ISHL 
    BIPUSH 9 
    IUSHR 
    ISTORE 6 

Спасибо. :)

+1

Очень редко для простой целочисленной арифметической операции значительная проблема производительности для современных процессоров. Условные ветви и промахи кэша гораздо более важны. –

ответ

3

Bytecode - это переносной промежуточный язык. Чтобы получить достойную производительность, современные JVMs скомпилируют его с собственным кодом точно в срок, поэтому не слишком много читайте в нем: то, что процессор фактически выполнит, может выглядеть совсем по-другому. Вам нужно будет проанализировать сгенерированный собственный код, чтобы иметь возможность делать выводы о том, почему X работает лучше, чем Y.

Как получить распечатку сгенерированного кода ассемблера зависит от JVM, см. Здесь инструкции для Hotspot (например, Oracle JDK и OpenJDK): http://mechanical-sympathy.blogspot.com/2013/06/printing-generated-assembly-code-from.html

0

В целом, операция переключения должна быть быстрее. Вот простой тест Java и результат значение:

int bits = 0b10111111110010100011110101110001; 

long time = System.nanoTime(); 
int significand; 
for (int i = 0; i < 1000000000; i++) { 
    significand = bits & 0b11111111111111111111111; 
} 
System.out.println(String.format("Time: %f (ms)", 
    (System.nanoTime() - time)/1000000f)); 

long time2 = System.nanoTime(); 
for (int i = 0; i < 1000000000; i++) { 
    significand = bits <<9>>> 9; 
} 
System.out.println(String.format("Time 2: %f (ms)", 
    (System.nanoTime() - time2)/1000000f)); 

Времени 1: 7.003190 (мс)
Время 2: 2.633435 (мс)

Это, конечно, приводит к огромному количеству повторений.

+0

Я профилировал свой код (JProfiler), и метод shinfting действительно кажется более быстрым (1.56x), но я искал несколько более общий ответ или, по крайней мере, подсказку, где искать, что я нашел в ответе Джони. В любом случае, спасибо. :) –

Смежные вопросы