Я видел следующий код и задавался вопросом о намерениях кодера. Связано ли это с производительностью автобокса?
map.put("doesntMatter", Boolean.TRUE);
Он мог бы сделать:
map.put("doesntMatter", true);
Есть ли польза от первого?
Я видел следующий код и задавался вопросом о намерениях кодера. Связано ли это с производительностью автобокса?
map.put("doesntMatter", Boolean.TRUE);
Он мог бы сделать:
map.put("doesntMatter", true);
Есть ли польза от первого?
Я написал пример:
public class Demo {
Map<String, Boolean> map = new HashMap<>();
void primitive() {
map.put("a", true);
}
void object() {
map.put("b", Boolean.TRUE);
}
}
посмотрите на байт-код primitive()
0 aload_0
1 getfield #17 <Demo/map Ljava/util/Map;>
4 ldc #24 <a>
6 iconst_1
7 invokestatic #26 <java/lang/Boolean/valueOf(Z)Ljava/lang/Boolean;>
10 invokeinterface #32 <java/util/Map/put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;> count 3
15 pop
16 return
и байт-код object()
0 aload_0
1 getfield #17 <Demo/map Ljava/util/Map;>
4 ldc #39 <b>
6 getstatic #41 <java/lang/Boolean/TRUE Ljava/lang/Boolean;>
9 invokeinterface #32 <java/util/Map/put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;> count 3
14 pop
15 return
Вывод:
при использовании примитива есть дополнительный шаг, вызывающий Boolean.valueOf()
, но если вы часто запускаете этот фрагмент кода, JIT-компилятор выполнит свою работу и оптимизирует его.
Map<String boolean>
?
- person David says Reinstate Monica; 21.06.2013
Map<String, boolean>
не компилируется. Я написал краткое заключение.
- person jlordo; 21.06.2013
invokestatic #26 <java/lang/Boolean/valueOf(Z)Ljava/lang/Boolean;>
.
- person Bhesh Gurung; 21.06.2013
Преимущества не во времени выполнения, как показывает этот небольшой тестовый код:
Результаты :
Time with primitives : 3334779619
Time with Object : 4092034749
Time with primitives : 3670851766
Time with Object : 2748035018
Time with Object : 3738916372
Time with primitives : 2975196722
Time with Object : 2514328271
Time with primitives : 2588980283
Time with Object : 2696162369
Time with primitives : 2615258656
Time with primitives : 2633824223
Time with Object : 2489779261
Код :
import java.util.HashMap;
import java.util.Map;
import javax.swing.JOptionPane;
public class Test
{
public static void main(String[] args) {
JOptionPane.showMessageDialog(null, "Start");
createWithPrimitive();
createWithObject();
createWithPrimitive();
createWithObject();
createWithObject();
createWithPrimitive();
createWithObject();
createWithPrimitive();
createWithObject();
createWithPrimitive();
createWithPrimitive();
createWithObject();
System.exit(0);
}
private static void createWithObject() {
long time = System.nanoTime();
Map<Integer, Boolean> testMap = new HashMap<Integer, Boolean>();
for (int i = 1; i <= 10000000; i++) {
if (i % 2 == 0) {
testMap.put(i, Boolean.TRUE);
} else {
testMap.put(i, Boolean.FALSE);
}
}
System.out.println("Time with Object : " + (System.nanoTime() - time));
}
private static void createWithPrimitive() {
long time = System.nanoTime();
Map<Integer, Boolean> testMap = new HashMap<Integer, Boolean>();
for (int i = 1; i <= 10000000; i++) {
if (i % 2 == 0) {
testMap.put(i, true);
} else {
testMap.put(i, false);
}
}
System.out.println("Time with primitives : " + (System.nanoTime() - time));
}
}
Из исходного кода -
public static final Boolean TRUE = new Boolean(true);
public Boolean(boolean value) {
this.value = value;
}
private final boolean value;
Итак, как видите, TRUE
вызывает конструктор, который просто устанавливает значение. Таким образом, теоретически он немного менее эффективен, потому что для получения того же результата требуется дополнительная работа.
static
.
- person Raedwald; 21.06.2013
Boolean.TRUE
не вызывает конструктор. Конструктор вызывается только один раз при загрузке класса. Boolean.TRUE
просто разыменовывает созданный объект.
- person jlordo; 21.06.2013
javap
, и, хорошо это или плохо,map.put("doesntMatter", true)
преобразуется вmap.put("doesntMatter", Boolean.valueOf(1))
. Поэтому он генерирует одну дополнительную инструкцию (которая помещает1
в стек перед вызовом методаvalueOf
) и используетinvokestatic
вместоgetstatic
(используется в первом операторе). Мне трудно делать какие-либо выводы из этого (потому что JIT вступит в игру, когда придет время; и разные компиляторы генерируют разные байт-коды), но то, что я только что описал, — это то, что на самом деле происходит с Oraclejavac
иjavap
. - person acdcjunior   schedule 21.06.2013Boolean
, а неboolean
. - person Raedwald   schedule 21.06.2013