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

Производительность Java: true vs. Boolean.TRUE

Что лучше с точки зрения производительности и эффективного использования памяти?

Boolean isItTrue(arg){ 
    return Boolean.TRUE;
}

boolean isItTrue(arg){
    return Boolean.TRUE
}

Boolean isItTrue(arg){
    return true;
}

boolean isItTrue(arg){
    return true;
}

Это должно быть быстрее и проще работать с примитивными типами, но в других случаях при использовании ссылки на статический объект не создается новое значение. Или может быть, он оптимизирован на уровне компилятора, и все true и false заменяются ссылками на статические объекты для сохранения памяти?

4b9b3361

Ответ 1

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


Ни один из примеров не включает создание экземпляров Boolean. Теоретически возможно, что 3 из 4 инициируют инициализацию класса Boolean... и что ваше приложение иначе не сделало бы этого. В этом очень маловероятном событии ваше приложение будет выделять 2 объекта, которые иначе не были бы выделены.


Этот будет равен или быстрее всех остальных, потому что это просто приводит к установке регистра на ноль.

boolean isItTrue(arg){
    return true;
}

Взятый изолированно, он должен загрузить статическую ссылку из памяти, а не нулевой регистр. Однако JIT-компилятор может в любой момент оптимизировать его.

Boolean isItTrue(arg){ 
    return Boolean.TRUE;
}

На первый взгляд это связано с вызовом Boolean.valueOf(true) в поле "true", но компилятор JIT должен иметь возможность оптимизировать его с тем же кодом, что и предыдущий, путем вложения вызова.

boolean isItTrue(arg){
    return true;
}

На первый взгляд это связано с призывом Boolean.booleanValue(Boolean.TRUE) к "распаковать" Boolean. Этот вызов может быть встроен. Также возможно, что компилятор JIT может не загружать ссылку на объект Boolean и получать его поле значения.

boolean isItTrue(arg){
    return Boolean.TRUE
}

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

Ответ 2

Если есть какое-либо усиление производительности, это настолько незначительно, что не имеет значения. Boolean.TRUE и Boolean.FALSE не возвращают новый объект в любом случае.

Ответ 3

Они будут намного быстрее. Я не думаю, что будет какая-то разница между этими двумя.

Boolean isItTrue(arg){ 
    return Boolean.TRUE;
}

boolean isItTrue(arg){
    return true;
}

Но другая реализация будет медленнее, потому что это будет упаковка, а распаковка на серверной части займет некоторое время процессора.


редактировать

Я собрал некоторые факты, реализовав 4 различных способа. Просто хочу поделиться этим с вами, я не знаю, если это - написать способ сделать это.

Boolean isItTrue(){ 
    return Boolean.TRUE;
}

Free Memory before start --> 16030936
Time taken in Secs --> 7.844
Free Memory After Process --> 15940472
Memory Usage --> 90464

boolean isItTrue(){
    return Boolean.TRUE;
}

Free Memory before start --> 16030936
Time taken in Secs --> 10.109
Free Memory After Process --> 15940472
Memory Usage --> 90464

Boolean isItTrue(){
    return true;
}

Free Memory before start --> 16030936
Time taken in Secs --> 7.906
Free Memory After Process --> 15940472
Memory Usage --> 90464

boolean isItTrue(){
    return true;
}

Free Memory before start --> 16030936
Time taken in Secs --> 7.828
Free Memory After Process --> 15940472
Memory Usage --> 90464

Основной класс

public static void main(String[] args){
    NewClass n = new NewClass();

    long sysTime = System.currentTimeMillis();

    Runtime rt = Runtime.getRuntime();
    long freeMem = rt.freeMemory();
    System.out.println( "Free Memory before start --> " + freeMem );
    for( int i = 0; i < Integer.MAX_VALUE; i++ ){
        n.isItTrue();
    }
    System.out.println( "Time taken in Secs --> " + (System.currentTimeMillis() - sysTime)/1000D);
    System.out.println( "Free Memory After Process --> " + rt.freeMemory() );
    System.out.println( "Memory Usage --> " + ( freeMem - rt.freeMemory() ) );
}

Ответ 4

Благоприятность для хранителя кода при таких микрооптимизациях. Вопрос не должен быть "который меньше/быстрее", сначала выражает то, что вы имеете в виду.

Если метод возвращает логический объект, то тот, кто получает, должен решить, есть ли вероятность, что он может быть нулевым, и что если он равен null, это может означать нечто отличное от true/false, как "мы не знаем".

Итак, возвращайте тип логического, если это то, что вы имеете в виду, в противном случае, если вы хотите разрешить Null, а затем Boolean.

Если возвращать логическое значение, то

return true; // or false

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

Если возвращать Boolean, то

return Boolean.TRUE

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

Ответ 5

Последний

boolean isItTrue(arg){
    return true;
}

Я использую Boolean только в том случае, если метод иногда должен возвращать null

Ответ 6

По этой логике ссылка на статический объект сама по себе столь же дорогостоящая, как и значение истины, если не больше.

Использование объектов может быть несколько медленнее, чем примитивы, но я бы не стал беспокоиться: разница не имеет значения.

Ответ 7

Используйте последний (только boolean). Даже если компилятор оптимизирует их все к одному и тому же, по крайней мере, вы упрощаете работу с компилятором (это вам нелегкая работа!).

Плюс это меньше нажатий клавиш (не нужно нажимать shift). Но на самом деле единственной причиной, по которой вы должны использовать класс-оболочку, является то, что вам нужно установить его на null и использовать в общих структурах данных, таких как LinkedList<E>.

Ответ 8

Мои эмпирические правила выглядят следующим образом:

  • Выбор по умолчанию - это примитивный тип (boolean).
  • Если мне нужна нулеустойчивость или нужно сохранить значения в контейнере, я использую класс (boolean).

Имея это в виду, мой выбор по умолчанию:

boolean isItTrue(arg){
    return true;
}

Что касается производительности, единственное, что кажется определенным, это то, что трудно представить сценарий, в котором использование boolean будет быстрее, чем использование boolean. Будет ли это медленнее или то же самое зависит от многих вещей, и вообще невозможно ответить.

Если вам действительно интересно, прокомментируйте код, в котором это важно!

Ответ 9

java.lang.Boolean принимает 16 байтов.

Это путь, если вы ищете только проблемы с производительностью и объемом памяти:

boolean isItTrue(arg){
    return true;
}