Dicas sobre como escrever micro benchmarks dos criadores do Java HotSpot :
Regra 0: Leia um artigo respeitável sobre JVMs e micro-benchmarking. Uma boa é Brian Goetz, 2005 . Não espere muito dos micro-benchmarks; eles medem apenas um intervalo limitado de características de desempenho da JVM.
Regra 1: Sempre inclua uma fase de aquecimento que execute o kernel de teste até o fim, o suficiente para acionar todas as inicializações e compilações antes da temporização das fases. (Menos iterações são boas na fase de aquecimento. A regra geral é várias dezenas de milhares de iterações do loop interno.)
Regra 2: Sempre executar com -XX:+PrintCompilation
, -verbose:gc
etc., para que possa verificar se o compilador e outras partes da JVM não estão fazendo um trabalho inesperado durante a sua fase de timing.
Regra 2.1: Imprima mensagens no início e no final das fases de temporização e aquecimento, para que você possa verificar se não há saída da Regra 2 durante a fase de temporização.
Regra 3: Esteja ciente da diferença entre-client
e -server
, e OSR e compilações regulares. A -XX:+PrintCompilation
bandeira relata compilações OSR com um sinal de arroba para denotar o ponto de entrada não-inicial, por exemplo: Trouble$1::run @ 2 (41 bytes)
. Prefira servidor ao cliente e regular ao OSR, se você estiver buscando o melhor desempenho.
Regra 4: Esteja ciente dos efeitos de inicialização. Não imprima pela primeira vez durante sua fase de temporização, pois a impressão carrega e inicializa as classes. Não carregue novas classes fora da fase de aquecimento (ou fase final do relatório), a menos que você esteja testando o carregamento da classe especificamente (e, nesse caso, carregue apenas as classes de teste). A regra 2 é sua primeira linha de defesa contra tais efeitos.
Artigo 5: Esteja ciente dos efeitos de desoptimização e recompilação. Não pegue nenhum caminho de código pela primeira vez na fase de temporização, porque o compilador pode colocar lixo e recompilar o código, com base em uma suposição otimista anterior de que o caminho não seria usado. A regra 2 é sua primeira linha de defesa contra tais efeitos.
Artigo 6: Use as ferramentas apropriadas para ler a mente do compilador e espere ser surpreendido pelo código que ele produz. Inspecione o código você mesmo antes de formar teorias sobre o que torna algo mais rápido ou mais lento.
Regra 7: Reduza o ruído em suas medições. Execute seu benchmark em uma máquina silenciosa e execute-o várias vezes, descartando discrepâncias. Use -Xbatch
para serializar o compilador com o aplicativo e considere a configuração -XX:CICompilerCount=1
para impedir que o compilador seja executado em paralelo consigo mesmo. Tente o seu melhor para reduzir a sobrecarga do GC, definir Xmx
(suficientemente grande) iguais Xms
e usarUseEpsilonGC
se estiver disponível.
Regra 8: use uma biblioteca para seu benchmark, pois provavelmente é mais eficiente e já foi depurado para esse único propósito. Tais como JMH , Caliper ou Bill e Paul's Excellent UCSD Benchmarks para Java .