Problema: quero um mapa que armazene um número inteiro como seu valor. Agora
tenho duas abordagens:
- Use qualquer coisa como chave e
Integer
(inteiro não primitivo) como valor, ou - Use qualquer coisa como chave e uma classe que contenha
int
(inteiro primitivo) como valor.
Qual devo usar? A primeira solução parece muito legal, nada
a fazer. Apenas instale o novo Integer
e pronto. Por outro lado, em termos de
desempenho, ele fará boxing / unboxing desnecessário se
não for manuseado corretamente. Lembre-se de que só podemos usar
inteiros primitivos para fazer cálculos e inteiros primitivos para armazenar valor
no mapa.
O teste
Benchmark withBoxing = new Benchmark() {
public void run() {
Map<String, Integer> a = new HashMap<String, Integer>();
// Simulate much boxing
for (int i = 0; i < MAX; i++) {
a.put("" + i, i);
}
// Simulate much unboxing
for (int i = 0; i < MAX; i++) {
// A hack so that JVM does not optimize this code.
hack += a.get("" + i);
hack = hack % 1000;
}
}
};
Benchmark encapsulate = new Benchmark() {
public void run() {
Map<String, EncapsulatedInteger> a = new HashMap<String, EncapsulatedInteger>();
// No boxing/unboxing, but new class
for (int i = 0; i < MAX; i++) {
a.put("" + i, new EncapsulatedInteger(i));
}
for (int i = 0; i < MAX; i++) {
// A hack so that JVM does not optimize this code.
hack += a.get("" + i).v;
hack = hack % 1000;
}
}
};
O comando de execução
javac MapPerf.java; java -Xmx1024m -cp . MapPerf
O resultado
$ javac MapPerf.java; java -Xmx1024m -cp . MapPerf
Boxing/unboxing: 10973 ms
Encapsulation: 7036 ms
Resumo
Com um Integer
valor, a rotina é 50% mais lenta por causa de
boxing / unboxing desnecessário