[Resolvido]Qual forma de medição gera mais impacto sobre os resultados?

Tenho duas dúvidas, a primeira já foi respondida pelo Felagund. A segunda continua.

Preciso avaliar o impacto que uma aplicação que gera checkpoints (baseada em serialização) tem sobre a execução total da aplicacão. Até o momento eu estava fazendo as medidas “na mão”, mas meu orientador sempre discorda dos resultados. Vocês podem me indicar alguma ferramenta que me permita medir os tempos de execução da aplicação??

[color=red] Segunda: [/color]

A outra é que meu professor acha que se eu fizer a medida armazenando o tempo em arquivos (a cada vez que executo o método run), vou introduzir uma distorção nos tempos que não vai existir se eu usar um array para guardar os tempos, e salvar o array em um arquivo somente quanto tiver todas as medidas.[color=red] Vocês acham que há diferença de performance entre o trecho 1 e o trecho 2?[/color]

Trecho 1:

	public void run()
	{
		try
		{
			File f = new File("D:\\Jeane\\zeligrid\\teste.txt");
			PrintWriter print = new PrintWriter(f);
			
			long tempoInicial = System.nanoTime();
			
			//código do método aqui
			
			long tempoFinal = System.nanoTime();
			long tempo = tempoFinal - tempoInicial;
			print.println(tempo);
			print.close();
			
		}
		catch(Exception e)
		{
			
		}	
	}

Trecho 2:

public void run()
	{
		try
		{
			long[] array = new long[200];
			long tempoInicial = System.nanoTime();
			
			//Código do método aqui
			
			long tempoFinal = System.nanoTime();
			long tempo = tempoFinal - tempoInicial;
			
			array[0] = tempo;
			
		}
		catch(Exception e)
		{
			
		}
		
	}

O que vocês acham? Obrigada!

Perf4j

http://blog.rollingwithcode.com/2009/08/perf4j-analise-de-performance-em-java.html

[]'s

Obrigada, Felagund!
Mas se alguém puder responder a segunda dúvida, ela continua de pé!

Que tipo de performance vc quer medir?
Consumo de memória? Dai a alternativa do arquivo sendo gravado o tempo todo é, em tese, a melhor.
Consumo de CPU? Dai a alternativa do array é a melhor, já que não precisa envolver o SO
Acesso a disco? Dai, com certeza, a alternativa do array é a melhor.

E tem vai depender do tamanho que esse teu array pode vir a ter.
Muitas milhões de entradas podem vir a ser um problema quando vc for realocar tudo, para adicionar um elemento novo. O que estou falando é:

int[] tempos = new int[10000000];
...
...
//ops! temos mais um tempo, que é o 10.000.001
//vou alocar 11 milhões de posições, para garantir
int[] tempos2 = new int[11000000];
System.arrayCopy(tempos, 0, tempos2, 0, tempos.length);
tempos = tempos2;
//agora posso usar o meu novo array, com 11 milhões de posições
tempos[10000000] = novoTempo;

esse arraycopy ali de cima pode vir a ser problemático

clone_zealot, obrigada pelas respostas. Eu quero medir o tempo que leva pra executar a aplicação mesmo. Dentro desse método run, entre as instruções

long tempoInicial = System.nanoTime(); e long tempoFinal = System.nanoTime(); está uma implementação do algoritmo de Fermat para teste de primalidade. É um algoritmo o(n). Eu preciso saber quantos nanosegundos essa implementação do algoritmo demora para determinar se um determinado número x é primo.

Na minha opinião, usar o arquivo não influencia no tempo medido porque eu manipulo o arquivo antes e depois de iniciar essa medição. Mas preciso ter certeza para não falar besteira pro meu orientador :smiley: .

Mais alguém pode ajudar?

Tem sim, JChrist. Seu professor está certo.

O salvamento em arquivos não é instantâneo. Como o HD é um dispositivo lento, demora para o SO localizar e gravar esse arquivo. O que ele faz então, é realizar suas operações em buffers, e fazer a gravação efetiva em paralelo.

E é essa execução em paralelo que poderá influenciar a execução do seu algoritmo.

Ok, ViniGodoy. A dúvida é:

1 - Eu começo a medir o tempo.
2 - O algoritmo é executado
3 - Eu paro de medir o tempo
4 - Calculo o tempo que levou pro algortimo executar (tempoFim - tempoInicio)
5 - Abro o arquivo em disco
6 - Escrevo o resultado em arquivo
7 - Encerro a aplicação

Ainda assim, manipulando o arquivo depois da execução do que eu quero medir, tem como o acesso a disco estar distorcendo o tempo medido??? :shock:

Se você fizer uma única vez, não. Mas se rodar uma única vez, também não terá um bom benchmark.

A virtual machine tem um tempo de “warmup”. Ou seja, um tempo que ela leva para inicializar valores internos, ou perceber que seu código merece fazer parte da compilação hotspot. Note que isso ocorre durante a execução do programa e não se pode garantir que ela esteja funcionando em sua capacidade total antes da primeira linha de código.

Geralmente, você deve inicializar o seu método e roda-lo algumas vezes sem gravar qualquer tipo de resultado. Só então você cria um vetor e roda novamente várias vezes, armazenando resultados, sem a geração de arquivos entre as execuções.

Depois, ao final, você pega os resultados todos e grava num arquivo, aproveitando para gerar quaisquer estatísticas que queira. Geralmente, gera-se o tempo médio, a média a cada x execuções e o desvio padrão.

Quase me esqueço. Também é boa uma sugerir a execução do garbage collector entre uma medição e outra.
Você faz isso usando o comando System.gc(). Isso atenua a possibilidade de uma recolhimento de lixo muito grande no meio dos seus testes.

Agora, o Java é uma péssima linguagem para microbenchmarking. Se você estiver validando uma técnica ou método, considere a possibilidade de escrever o código em C++.

Não deixe também de ler esses artigos:


[quote=J-Chist]T
[color=red] Segunda: [/color]

A outra é que meu professor acha que se eu fizer a medida armazenando o tempo em arquivos (a cada vez que executo o método run), vou introduzir uma distorção nos tempos que não vai existir se eu usar um array para guardar os tempos, e salvar o array em um arquivo somente quanto tiver todas as medidas.[color=red] Vocês acham que há diferença de performance entre o trecho 1 e o trecho 2?[/color]
[/quote]

Antes que alguem sugira usar um profiler a questão não é performance.
Quando vc usa arquivos vc usa operações de I/O. Estas operações demoram um tempo maior que escrever em um array.
Então seu processo demora X +dt onde dt é o tempo de gravar a info. Este dt será maior para arquivos do que para array.
A ideia é que se usar array dt poderá ser despresável (ou seja, pode se assumir que dt ~ 0) , com I/O não pode assumir isso.

A medição sim altera o resultado se X for da ordem inferior a dt. com I/O isso é bem provável que aconteça e portanto I/O
deve ser evitado.

Ahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh…Agora sim!!
Valeu galera!