2015-06-24 6 views
2

Я видел в изрядном количестве Java кода что-то вроде этого:Отрицание Интс в Java

int blah = ~someFunc() + 1; 

вместо

int blah = -1 * someFunc(); 

есть ли реальная разница в результатах здесь? Явак распознает разницу между этими двумя случаями? Кажется, компилятор должен иметь возможность преобразовать эти две строки в один и тот же байтовый код.

Редактировать: Это не о , так как бит работает, это вопрос о том, почему разработчик может выбрать определенный подход к операции.

Edit2: Я сделал javap -c на простом тесте и вот некоторые JVM байт-код:

int one = -1 * someFunc(); 
0: iconst_m1  
1: invokestatic #2     // Method someFunc:()I 
4: imul   
5: istore_1  

int two = ~someFunc() + 1; 
6: invokestatic #2     // Method someFunc:()I 
9: iconst_m1  
10: ixor   
11: iconst_1  
12: iadd   
13: istore_2  

Таким образом, есть еще 3 ява инструкции для битном флипа (который iconst_m1, ixor) плюс один, но, как это переводится в машинные циклы, вероятно, очень специфично для архитектуры.

+0

Компилятор/интерпретатор не может быть достаточно умен, чтобы различать во всех случаях, но я думаю, что то, что вы видите, - это просто прихоть программиста, как он это делает. В великой схеме вещей '*' * может быть немного менее эффективным, но я сомневаюсь в этом. Может быть, программист демонстрирует свои побитовые знания? ;) – lurker

+0

Возможный дубликат [Как работает оператор побитового дополнения (~)?] (Http://stackoverflow.com/questions/791328/how-does-the-bitwise-complement-operator-work) –

+2

@RamanShrivastava I не думайте, что это дубликат. OP не спрашивает *, как * '~' используется для отрицания значения (как он работает). OP задается вопросом, почему * он используется вместо '-1 *'. – lurker

ответ

1

Говоря строго расходов на обучение, первый подход действительно может быть быстрее (на некоторых процессорах): К примеру, посетить http://www.agner.org/optimize/instruction_tables.pdf и сравните стоимость операций:

IMUL r32 = 3 ops 
ADD = 1 op 
NOT = 1 op 

Таким образом, вы можете сохранить один операция. С другой стороны, каждый вызов функции требует, чтобы вы клали vars на стек регистров и извлекали их из него, что добавляет дополнительные затраты.

+2

На Intel код операции «neg» требует только одного оп. И 'add 1' будет состоять из двух операций на многих системах. Таким образом, это может сильно различаться в зависимости от вашей машины и вашего компилятора. Комментарий выше о «нано-оптимизации», вероятно, лучший. Это глупо, потому что оно скрывает ваше истинное намерение, и * в лучшем случае * сохраняет только один op. – markspace

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

  • Нет связанных вопросов^_^