Eu gostaria de medir o tempo que leva para repetir a execução de uma função. São
replicate()
e usando loops for equivalentes? Por exemplo:system.time(replicate(1000, f())); system.time(for(i in 1:1000){f()});
Qual é o método preferido?
Na saída de
system.time()
, ésys+user
o tempo real da CPU para executar o programa? Éelapsed
uma boa medida do desempenho do tempo do programa?
36
Respostas:
Para um cronograma eficaz dos programas, especialmente quando você estiver interessado em comparar soluções alternativas, você precisa de um controle! Uma boa maneira é colocar o procedimento que você está cronometrando em uma função. Chame a função dentro de um loop de temporização. Escreva um procedimento stub, basicamente retirando todo o código da sua função e retornando (mas deixe todos os argumentos). Coloque o esboço no seu loop de tempo e volte a cronometrar. Isso mede toda a sobrecarga associada ao tempo. Subtraia o tempo do stub do tempo do procedimento para obter a rede: essa deve ser uma medida precisa do tempo real necessário.
Como a maioria dos sistemas hoje em dia pode ser interrompida peremptoriamente, é importante executar várias execuções de tempo para verificar a variabilidade. Em vez de executar uma longa execução de segundos, faça m execuções de cerca de N / mN m N/ m segundos cada. Isso ajuda a fazer isso em um loop duplo de uma só vez. Não só é mais fácil de manusear, como também introduz um pouco de correlação negativa em cada série temporal, o que realmente melhora as estimativas.
Ao usar esses princípios básicos do design experimental, você controla essencialmente quaisquer diferenças devido à maneira como implanta o código (por exemplo, a diferença entre um loop for e replicate ()). Isso faz o seu problema desaparecer.
fonte
Em relação aos seus dois pontos:
replicate()
, pois é funcional.elapsed
, ou seja, o terceiro número.O que costumo fazer é
para obter uma média aparada de 90% de N repetições de chamada
f()
.(Editado, com agradecimentos a Hadley por pegar um thinko.)
fonte
mean(replicate(N, system.time(f(...))[3]), trim = 0.05)
?Você também pode cronometrar com timesteps retornados por
Sys.time
; é claro que isso mede o tempo da parede, então o tempo de computação em tempo real. Código de exemplo:fonte
Quanto à métrica de tempo a ser usada, não posso adicionar aos outros respondedores.
Em relação à função a ser usada, eu gosto de usar o benchmark? Do pacote rbenchmark .
fonte
Eles fazem coisas diferentes. Cronometre o que você deseja fazer. replicate () retorna um vetor de resultados de cada execução da função. O loop for não. Portanto, não são declarações equivalentes.
Além disso, cronometre várias maneiras pelas quais você deseja que algo seja feito. Então você pode encontrar o método mais eficiente.
fonte