Pergunta

Alguém já usa o benchmarking Stopwatch ou uma ferramenta de desempenho sempre deve ser usada? Existem boas ferramentas gratuitas disponíveis para Java? Quais ferramentas você usa?

Para esclarecer minhas preocupações, o benchmarking Stopwatch está sujeito a erro devido ao agendamento do sistema operacional. Em uma determinada execução do seu programa, o sistema operacional pode agendar outro processo (ou vários) no meio da função que você está cronometrando. Em Java, as coisas são um pouco piores se você estiver tentando cronometrar um aplicativo rosqueado, pois o agendador da JVM lança um pouco mais de aleatoriedade na mistura.

Como você aborda a programação do sistema operacional ao fazer benchmarking?

Foi útil?

Solução

O benchmarking StopWatch está bem, desde que você meça o suficiente iterações para serem significativas. Normalmente, preciso de um tempo total decorrido de algum número de segundos de um dígito. Caso contrário, seus resultados são facilmente distorcidos significativamente pela programação e outras interrupções de O/S para o seu processo.

Para isso, eu uso um pequeno conjunto de métodos estáticos que construí há muito tempo, que são baseados em System.currentTimeMillis().

Para o trabalho de perfil que usei JProfiler por vários anos e achei muito bom. Eu olhei recentemente YourKit, o que parece ótimo no site, mas eu não o usei pessoalmente.

Para responder à pergunta sobre o agendamento de interrupções, acho que fazer corridas repetidas até que a consistência seja alcançada/observada obras na prática para eliminar resultados anômalos da programação de processos. Também acho que o agendamento de threads não tem impacto prático para execuções entre 5 e 30 segundos. Por fim, depois de passar os poucos segundos, o agendamento do limite tem, na minha experiência, impacto insignificante nos resultados - acho que uma corrida de 5 segundos é de forma consistente de média da mesma forma que uma corrida de 5 minutos para o tempo/iteração.

Você também pode considerar pré -unindo o código testado cerca de 10.000 vezes para "aquecer" o JIT, dependendo do número de vezes que você espera que o código testado seja executado ao longo do tempo na vida real.

Outras dicas

É totalmente válido, desde que você mede intervalos grandes o suficiente. Eu executaria 20 a 30 corridas do que você pretende testar para que o tempo total decorrido seja superior a 1 segundo. Percebi que os cálculos de tempo baseados no sistema.currenttimemillis () tendem a ser 0ms ou ~ 30ms; Eu não acho que você possa obter algo mais preciso do que isso. Você pode querer experimentar o sistema.nanotime () se você realmente precisar medir um pequeno intervalo de tempo:

Um perfilador fornece informações mais detalhadas, o que pode ajudar a diagnosticar e corrigir problemas de desempenho.

Em termos de medição real, o tempo de cronômetro é o que os usuários notam; portanto, se você deseja validar que as coisas estão dentro dos limites aceitáveis, o tempo de parada é bom.

Quando você quer corrigir problemas, no entanto, um perfilador pode ser realmente útil.

Stopwatch é realmente o melhor referência!

O tempo de resposta do usuário final a fim é o tempo que realmente importa.

Nem sempre é possível obter esse tempo usando as ferramentas disponíveis, por exemplo, a maioria das ferramentas de teste não inclui o tempo necessário para um navegador renderizar uma página, de modo que uma página de excesso com CSS mal escrita mostrará o segundo tempo de resposta ao teste Ferramentas, mas 5 segundos mais tempo de resposta ao usuário.

As ferramentas são ótimas para testes automatizados e para determinação de problemas, mas não perdem de vista o que você realmente deseja medir.

Você precisa testar um número realista de iterações, pois obterá respostas diferentes, dependendo de como testar o tempo. Se você executar apenas uma operação uma vez, poderá ser enganoso tomar a média de muitas iterações. Se você quiser saber o tempo que leva após a JVM aquecer, você pode executar muitas (por exemplo, 10.000) que não estão incluídas nos horários.

Eu também sugiro que você use System.nanoTime() como é muito mais preciso. Se o tempo de teste for de cerca de 10 micro-segundos ou menos, você não deseja chamar isso com muita frequência ou isso pode alterar seu resultado. (por exemplo, se estou testando por exemplo, 5 segundos e quero saber quando isso acabar, só recebo o nanotime a cada 1000 iterações, se eu sei que uma iteração é muito rápida)

Como você aborda a programação do sistema operacional ao fazer benchmarking?

Referência para longo O suficiente em um sistema representativo da máquina que você usará. Se o seu sistema operacional diminuir seu aplicativo, isso deve fazer parte do resultado.

Não faz sentido dizer que meu programa seria mais rápido, se eu não tivesse um sistema operacional.

Se você está usando Linux, você pode usar ferramentas como numactl, chrt e taskset Para controlar como as CPUs são usadas e a programação.

Os perfiladores podem atrapalhar os horários, então eu usaria uma combinação de tempo de parada para identificar problemas gerais de desempenho e, em seguida, usar o Profiler para descobrir onde está gasto o tempo. Repita o processo conforme necessário.

Afinal, é provavelmente a segunda forma mais popular de benchmarking, logo após o "benchmarking sem observação" - onde dizemos "essa atividade parece lenta, que uma parece rápida".

Normalmente, o mais importante para otimizar é o que interfere na experiência do usuário - que geralmente é uma função de com que frequência você executa a ação e o que mais estiver acontecendo ao mesmo tempo. Outras formas de benchmarking geralmente ajudam a se concentrar nelas.

Eu acho que uma questão -chave é a complexidade e o tempo de tempo da operação.

Às vezes, até uso medições físicas de cronômetro para ver se algo leva minutos, horas, dias ou até semanas para calcular (estou trabalhando com uma aplicação em que os tempos de execução nas ordens de vários dias não são inéditos, mesmo que segundos e minutos sejam o tempo mais comum se estende).

No entanto, a automação oferecida por chamadas para qualquer tipo de sistema de relógio no computador, como a chamada de Java Millis mencionada no artigo vinculado, é claramente superior a ver manualmente quanto tempo acontece.

Os perfiladores são bons, quando funcionam, mas tive problemas para aplicá-los ao nosso aplicativo, o que geralmente envolve geração dinâmica de código, carregamento dinâmico de DLLs e trabalho realizado nas duas linguagens de script com compilação just-in-time interno de Minha aplicação. Eles costumam ser limitados a assumir um único idioma de origem e outras expectativas irreais para software complexo.

Eu publiquei um programa hoje que pesquisou e coletava informações de vários arquivos do DBASE, levou apenas uma hora para correr. Eu dei uma olhada no código, fiz um palpite educado no que era o gargalo, fiz uma pequena melhoria no algoritmo e re-reancreto o programa, desta vez ele concluído em 2,5 minutos.

Eu não precisava de nenhuma ferramenta sofisticada ou suítes de referência para me dizer que a nova versão foi uma melhoria significativa. Se eu precisasse otimizar ainda mais o tempo de execução, provavelmente teria feito algumas análises mais sofisticadas, mas isso não era necessário. Acho que esse tipo de "parada de benchmarking" é uma solução aceitável em vários casos e recorrer a ferramentas mais avançadas seria realmente mais demorado nesses casos.

Eu não acho que o benchmarking Stopwatch é horrível demais, mas se você puder entrar em uma máquina Solaris ou OS X, verifique o Dtrace. Eu usei para obter ótimas informações sobre o tempo em meus aplicativos.

Eu sempre uso o benchmarking StopWatch, pois é muito mais fácil. Os resultados não precisam ser muito precisos para mim. Se você precisar de resultados precisos, não deve usar o benchmarking Stopwatch.

Eu faço isso o tempo todo. Eu prefiro usar um perfilador, mas o fornecedor da linguagem específica do domínio com quem estou trabalhando não fornece um.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top