|
|
Rafael Steil
Veja possíveis problemas que você pode ter com arrays multi-dimensionais, e como resolver isso.
Muitas dimensões são ruins para você
Bem vindo à edição de número 70 da The Java(tm) Specialists' Newsletter, onde daremos uma breve olhada em arrays multi-dimensionais. Vários artigos estão disponíveis sobre este problema, então, nesta newsletter, irei direto ao ponto com um exemplo. Gostaria de agradecer a Roy Emmerich (Peralex in Cape Town), Pieter Potgieter e Louis Pool from Grintek Ewation por me lembrarem deste problema e por enviarem um programa de teste que ilustra isso.
Uma das coisas que aprendemos na escola primária do Java é que devemos evitar arrays multi-dimensionais assim como evitamos uma praga. Um array é um objeto por natureza, e quando você tem arrays de várias dimensões, você tem arrays de objetos. Navegar por eles consome um processamento considerável. Ao invés de construir um array multi-dimensional de tamanho n por m, construa um array de uma única dimensão de tamanho n vezes m e então calcule a posição você mesmo.
01 public class MultiDimensions {
02 private final static int NUM_BINS = 1000;
03 private final static int ITERATIONS = 10000;
04
05 public static void main(String[] args) {
06 testMultiArray();
07 testMultiArray2();
08 testSingleArray();
09 }
10
11 private static void testMultiArray() {
12 long time = -System.currentTimeMillis();
13 // Apenas certificando que o número de operações é igual
14 int ops = 0;
15
16 for (int repeat = 0; repeat < ITERATIONS; repeat++) {
17 int[][] aTwoDim = new int[NUM_BINS][4];
18 for (int i = 0; i < aTwoDim.length; i++) {
19 for (int j = 0; j < aTwoDim[i].length; j++) {
20 ops++;
21 aTwoDim[i][j] = j;
22 }
23 }
24 }
25
26 time += System.currentTimeMillis();
27 System.out.println(ops);
28 System.out.println("Tempo necessário para [][4] - " + time);
29 }
30
31 private static void testMultiArray2() {
32 long time = -System.currentTimeMillis();
33 int ops = 0;
34
35 for (int repeat = 0; repeat < ITERATIONS; repeat++) {
36 int[][] aTwoDim = new int[4][NUM_BINS];
37 for (int i = 0; i < aTwoDim.length; i++) {
38 for (int j = 0; j < aTwoDim[i].length; j++) {
39 ops++;
40 aTwoDim[i][j] = j;
41 }
42 }
43 }
44
45 time += System.currentTimeMillis();
46 System.out.println(ops);
47 System.out.println("Tempo necessário para [4][] - " + time);
48 }
49
50 private static void testSingleArray() {
51 long time = -System.currentTimeMillis();
52 int ops = 0;
53
54 for (int repeat = 0; repeat < ITERATIONS; repeat++) {
55 int[] aOneDim = new int[NUM_BINS * 4];
56 for (int i = 0; i < aOneDim.length/4; i++) {
57 for (int j = 0; j < 4; j++) {
58 ops++;
59 aOneDim[i*4 + j] = j;
60 }
61 }
62 }
63
64 time += System.currentTimeMillis();
65 System.out.println(ops);
66 System.out.println("Tempo necessário para [] - " + time);
67 }
68 }
|
Em meus testes usando um cliente hotspot JDK 1.4.1, tive o seguinte resultado:
40000000
Tempo necessário para [][4] - 4226
40000000
Tempo necessário para [4][] - 631
40000000
Tempo necessário para [] - 671
|
Com um hotspot server, os resultados são ligeiramente melhores:
40000000
Tempo necessário para [][4] - 3675
40000000
Tempo necessário para [4][] - 350
40000000
Tempo necessário para [] - 561
|
Os resultados são esclarecedores. Se voce tem um array com um index primário grande, você se dará melhor usando um array de dimensão única. Sob o server hotspot, o array multi-dimensional com um index primário pequeno se sai um pouco melhor que o array de dimensão única.
Vendo mais cuidadosamente...
Um de nossos assinantes, Martin Schulte, da Alemanha, enviou uma correção para a última newsletter, e eu não gostaria de esperar muito tempo para publicar a correção, uma vez que é bem significante.
Martin descobriu que a maior diferença na performance é na criação de arrays multi-dimensionais. Mark Grand também pensou que eu deveria retificar que não há arrays multi-dimensionais no Java, somente arrays de arrays. Esta é a razão que temos uma diferença na performance quando criamos tais arrays de arrays
A diferença no tempo de criação pode ser vista no pequeno exemplo abaixo. Deixei sem o sintax highlighting para ver a sua reação ;-)
01 public class CreationTimes {
02 private final static int ITERATIONS = 1000000;
03 private final static int NUM_BINS = 20;
04 private final static int THE_OTHER_DIM = 4;
05
06 public static void main(String[] args) {
07 testMultiArray();
08 testMultiArray2();
09 testSingleArray();
10 }
11
12 private static void testMultiArray() {
13 long time = -System.currentTimeMillis();
14
15 for (int repeat = 0; repeat < ITERATIONS; repeat++) {
16 int[][] aTwoDim = new int[NUM_BINS][THE_OTHER_DIM];
17 }
18
19 time += System.currentTimeMillis();
20 System.out.println("Tempo necessário para [][" + THE_OTHER_DIM + "] - " +
21 time);
22 }
23
24 private static void testMultiArray2() {
25 long time = -System.currentTimeMillis();
26
27 for (int repeat = 0; repeat < ITERATIONS; repeat++) {
28 int[][] aTwoDim = new int[THE_OTHER_DIM][NUM_BINS];
29 }
30
31 time += System.currentTimeMillis();
32 System.out.println("Tempo necessário para [" + THE_OTHER_DIM + "][] - " +
33 time);
34 }
35
36 private static void testSingleArray() {
37 long time = -System.currentTimeMillis();
38
39 for (int repeat = 0; repeat < ITERATIONS; repeat++) {
40 int[] aOneDim = new int[NUM_BINS * THE_OTHER_DIM];
41 }
42
43 time += System.currentTimeMillis();
44 System.out.println("Tempo necessário para [] - " + time);
45 }
46 }
|
O resultado the rodar este código é o seguinte:
Tempo necessário para [][4] - 9653
Tempo necessário para [4][] - 2394
Tempo necessário para [] - 671
|
Atenciosamente,
Heinz
Sobre a The Java Specialists Newsletter
Este artigo é fruto de uma parceria entre o GUJ e o autor da The Java Specialists Newsletter, Dr. Heinz M. Kabutz. Originalmente publicadas em inglês e enviadas para milhares de leitores ao redor do planeta, o GUJ propô-se a realizar a tradução para o Português do conteúdo, disponibilizando assim um ótimo material para um número ainda maior de leitores.
Você encontra o documento original, assim como newsletters anteriores, no site oficial, em http://www.javaspecialists.co.za.
|
|
|