Подтвердить что ты не робот

Проверяет логическое значение быстрее, чем установка boolean в java?

Это:

if (var) {
    var = false;
}

В сравнении с этим:

var = false;

Есть ли разница в скорости?

4b9b3361

Ответ 1

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

  • Прогнозирование ветвей - если var почти всегда ложно, это то, что предлагает код, предиктор ветки будет почти всегда прав. Если поле меняется часто, то это станет часто ошибочной ветвью и будет дорогостоящим.

  • Прочитать miss - Если var в основном читается (и читает LOT), то избегать изменения без причины может помочь вашему программному обеспечению, не отменив лимит кэша, на котором он сидит. Если вы напишете на него все другие ядра, которые его читают (и что-нибудь в одной строке кеша), вам нужно будет получить новую копию, испытывающую прочтение прочтения. Это означает, что вышеупомянутый метод может стоить медленнее, чтобы сделать чтение более стабильной.

  • Записать стоимость затрат на чтение - если var является изменчивым, тогда он пишет барьер LoadStore, который довольно дорог. Чтение изменчивого (барьер LoadLoad) довольно дешево по сравнению (кеш-хит для часто используемого и малозначимого значения). Это может сделать отрасль очень дешевой по сравнению.

Это люди, которые делают оптимизацию, и примеры можно найти в JDK (IIRC), я предполагаю, что у вас есть причина его рассмотреть.

Ответ 2

первый код содержит сравнение, поэтому ваш компилятор может создать java-байт-код, который выглядит так:

  public static void main(java.lang.String[]);
    Code:
       0: iconst_1      
       1: istore_1      
       2: iload_1       
       3: ifeq          8
       6: iconst_0      
       7: istore_1      
       8: return    

Для второго кода сгенерированный байт-код короче, потому что сравнение отсутствует:

  public static void main(java.lang.String[]);
    Code:
       0: iconst_1      
       1: istore_1      
       2: iconst_0      
       3: istore_1      
       4: return      

Виртуальной машине требуется больше времени для выполнения 8 команд в первом примере, чем 4 команды во втором. Хотя это различие не должно быть высоким, второй код более четко.

Поместите свой код в простой основной метод и скомпилируйте класс. Затем запустите командную строку и перейдите в каталог java/bin. Разберите вызов класса javap -c path/to/YourClass.class >> path/to/bytecode.txt. bytecode.txt будет содержать java-байт-код вашего класса.

Ответ 3

Я опоздал на игру, но я написал этот тестовый класс, чтобы ответить на аналогичный вопрос.

package SpeedTests;

import java.text.NumberFormat;
import java.util.Locale;

public class BooleanSpeedTest {

    public static void main(String[] args) {
        boolean BoolTest = true;
        long LongLoop = 100000;
        long TrueLoopCount = 0;
        long FalseLoopCount = 0;
        long TimeTotal = 0;

        long startTime;
        long endTime;

        for(int intLoopA = 1; intLoopA < 6; intLoopA++) {
            LongLoop = LongLoop * 10;
            TimeTotal = 0;
            System.out.println("");
            System.out.print(
                    NumberFormat.getNumberInstance(Locale.US).format(LongLoop) + " - ");

            for(int intLoopM = 0; intLoopM < 20; intLoopM++) {
                TrueLoopCount = 0;
                FalseLoopCount = 0;
                startTime = System.currentTimeMillis();

                for(long LoopCount = 0; LoopCount < LongLoop; LoopCount++) {
                    if(!BoolTest) {
                        TrueLoopCount++;
                    }
                    else
                        FalseLoopCount++;   
                }
                endTime = System.currentTimeMillis();
                System.out.print( (endTime - startTime) + "ms ");
                TimeTotal += ((endTime - startTime) );    
            }

            System.out.print(" AVG: " + (TimeTotal/20));
        }
    }
}

Мои результаты: среднее время/миллиард (мс) Примечания Время за цикл

if(BoolTest)                    443                     When False      0.00000443
if(BoolTest)                    443                     When True

if(BoolTest == false)           443                     When False
if(BoolTest == false)           442                     When True

if(!BoolTest)                   438                     When False      
if(!BoolTest)                   441                     When True

(BoolTest ? Var++ : Var--)      435                     When True
(BoolTest ? Var++ : Var--)      435                     When False

Ответ 4

"Разница в скорости", если таковая имеется, будет полностью зависеть от JVM. Любой достойный компилятор должен иметь возможность оптимизировать прохождение теста, после чего два идентичны.

Исключение: если var объявлено volatile, условная версия будет всегда медленнее.

В любом случае, если производительность критическая, наилучшим вариантом является измерение ее в ожидаемых условиях (машина, система, JVM, типичная нагрузка и т.д.).

Ответ 5

Вот еще один дешевый "эталон" (который почти не заслуживает этого термина). Для меня результаты теста Monkey Wrench не были четко изложены в отношении OP-вопроса, поэтому я подумал, что должен поставить его и здесь.

Результат (в этих условиях и только в нескольких тестах): проверять локальное логическое значение перед записью лучше, чем писать часто, если не нужно.

public static void main(String[] args) {

    final Random r = new Random(0);

    boolean b = false;
    boolean decision;

    long startTime;
    long endTime;

    startTime = System.currentTimeMillis();
    for (long i = 0; i < 1000000000; i++) {
        decision = r.nextDouble() > 0.1; // Will be true MOST of the time.

        if (decision) {

            // if (!b) {
                b = true;
            // }

        }
    }
    endTime = System.currentTimeMillis();

    System.err.println(endTime - startTime);
    System.err.println(b);

    System.exit(0);
}

With bluntly writing (ms):
18139
18140
18196
(18220)
(18181)
----------
Average of 3: 18158.333333333333333333333333333
Average of 5: 18175.2


With checking before writing (ms):
18097
18109
18115
(18129)
(18133)
----------
Average of 3: 18107
Average of 5: 18116.6


With checking, it only takes this % (3 samples): 99.71730151445617255621844882974
With checking, it only takes this % (5 samples): 99.677582640080989480170782164708

При проверке это занимает около 99,7% времени тупой записи. Если запись в противном случае произойдет излишне очень часто. В этом дерьмовом "эталоне", то есть.