Vou entrar em um projeto de otimização de sistema, ou seja, basicamente vou pegar uma ronita altera-la e após a alteração a mesma deve atingir os mesmos objetivos porém de uma forma muito mais rapida.
Tenho uma boa base de analise de algoritmos, identificar se o mesmo é lg n, O(N), etc … porém quero ir mais afundo!
Quero saber a nível de custo de comando:
Por exemplo: o que custa mais para o processador, um pré ou um pós encremento?!
Outro exemplo: O que custa mais um for ou um while …
A tambem tenho uma boa base de assembler e alguns comandos consigo deduzir como o comando fica na linguagem de maquina e dai consigo tirar um achismo de qual custa mais…
Alguém possui alguma apostila sobre isso, livro para indicação, alguma fonte de conhecimento?!
Sei que a experiência seria a melhor, porém to querendo da uma adiantada, )
Cara, eu tenho algumas documentações impressas a respeito disso. Porém estou no trabalho, quando chegar em casa, dou uma olhada e t dou um toque… este é um assunto que me interessa bastante…
Se seu sistema usar bancos de dados como o Oracle, por exemplo, você pode fazer análise de custo das próprias queries do sistema, melhorando a performance dos comandos. É o que os DBAs chamam de “tunning”.
Cara na atual edição da Mundo Java tem uma matéria sobre Profile em aplicações Java, não sei se é exatamente isso que você precisa, mas segue o link, na matéria ensina a usar um plugin do Eclipse para esses testes.
No primeiro caso: tanto faz. No segundo caso: tanto faz.
É um bocado difícil, dado um código Java, determinar “só de olhar” qual é mais rápido, a menos que o algoritmo seja totalmente diferente (se um é O(n^2) e outro é O(log n) então dá para saber que para n suficientemente grande, o algoritmo O(log n) é mais rápido).
De modo geral:
Dependendo do processador, o “JIT” (“just-in-time compiler”) gera código diferente. Por exemplo, se ele estiver rodando em um P-IV gera código diferente de quando ele roda em um P-III ou um Athlon.
Código mais bobo otimiza melhor que código muito “esperto”.
Não saia de um loop com uma exception; saia usando uma condição.
Há muitas variáveis (como “cache hits & misses”, e outras coisas) que tornam extremamente difícil determinar a velocidade relativa de um código em relação a outro, sem rodar o código e fazer uma série de benchmarks.
Só para ter uma idéia de como não adianta usar truques de programação, eis os resultados de um benchmark:
import java.util.Arrays;
class TesteLoop {
/**
* Para cada iteração faço um teste
*/
public static long teste1(final double[] array) {
long t = System.currentTimeMillis();
final int n = array.length;
for (int i = 0; i < n; ++i) {
array[i] = Math.PI;
}
return System.currentTimeMillis() - t;
}
/**
* Para cada iteração não faço teste nenhum
*/
public static long teste2(final double[] array) {
long t = System.currentTimeMillis();
int i = 0;
try {
while (true) {
array[i++] = Math.PI;
}
} catch (ArrayIndexOutOfBoundsException ex) {
}
return System.currentTimeMillis() - t;
}
/**
* Para cada iteração faço um teste, mas contra 0
*/
public static long teste3(final double[] array) {
long t = System.currentTimeMillis();
for (int i = array.length - 1; i >= 0; --i) {
array[i] = Math.PI;
}
return System.currentTimeMillis() - t;
}
/**
* Para cada iteração não faço teste nenhum
*/
public static long teste4(final double[] array) {
long t = System.currentTimeMillis();
int i = array.length;
try {
while (true) {
array[--i] = Math.PI;
}
} catch (ArrayIndexOutOfBoundsException ex) {
}
return System.currentTimeMillis() - t;
}
// Usando o que já está pronto
public static long teste5 (final double[] array) {
long t = System.currentTimeMillis();
Arrays.fill (array, Math.PI);
return System.currentTimeMillis() - t;
}
public static void warmup () {
double[] array = new double [400000];
for (int i = 0; i < 1000; ++i) {
teste1(array);
teste2(array);
teste3(array);
teste4(array);
teste5(array);
}
}
public static void teste() {
double[] array = new double [400000];
long[] acc = new long[1+5];
for (int i = 0; i < 2000; ++i) {
acc[1] += teste1 (array);
}
for (int i = 0; i < 2000; ++i) {
acc[2] += teste2 (array);
}
for (int i = 0; i < 2000; ++i) {
acc[3] += teste3 (array);
}
for (int i = 0; i < 2000; ++i) {
acc[4] += teste4 (array);
}
for (int i = 0; i < 2000; ++i) {
acc[5] += teste5 (array);
}
System.out.println ("Teste 1: média = " + (acc[1] / 2000.0) + " ms");
System.out.println ("Teste 2: média = " + (acc[2] / 2000.0) + " ms");
System.out.println ("Teste 3: média = " + (acc[3] / 2000.0) + " ms");
System.out.println ("Teste 4: média = " + (acc[4] / 2000.0) + " ms");
System.out.println ("Teste 5: média = " + (acc[5] / 2000.0) + " ms");
}
public static void main(String[] args) {
// Warm-up
System.out.println ("Efetuando o warm-up");
warmup();
// Teste real
System.out.println ("Efetuando o teste real");
teste();
}
}
Resultados:
C>\jdk1.6.0\bin\java -Xms128m -Xmx128m -XX:+AggressiveOpts
-server -cp . TesteLoop
Efetuando o warm-up
Efetuando o teste real
Teste 1: média = 4.1245 ms
Teste 2: média = 4.422 ms
Teste 3: média = 4.148 ms
Teste 4: média = 4.203 ms
Teste 5: média = 4.195 ms
Ou seja, sair de um loop com uma exception não é um bom negócio.
No primeiro caso: tanto faz. No segundo caso: tanto faz.
[/quote]
HuahuHUHAUhuAHUhu!
Foi apenas um exemplo, sabia que ia dar na mesma, coloquei para que o pessoal entende-se até aonde queria chegar…
Sei que o meu objetivo é mirabolante, porém não custa tentar…
Sobre a exception … não apenas em um loop mas em qualquer parte do código se concluir que lançar uma exception demora mais!!!
Tecnoage to esperando esse material com ansiedade!
thingol belo exemplo … é bem por ai meu raciocínio… to modificando o código e colocando um time para verificar o que eu to modificando, talvez milésimos de segundos ou nanossegundos em apenas um rotina não faça diferença, porém são muitas classes que rodam muitas vezes diariamente…